55 * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
66 */
77
8+ #include <linux/bitfield.h>
89#include <linux/clk.h>
910#include <linux/completion.h>
1011#include <linux/i2c.h>
3334#define REG_CTRL_ACK_IGNORE BIT(1)
3435#define REG_CTRL_STATUS BIT(2)
3536#define REG_CTRL_ERROR BIT(3)
36- #define REG_CTRL_CLKDIV_SHIFT 12
37- #define REG_CTRL_CLKDIV_MASK GENMASK(21, 12)
38- #define REG_CTRL_CLKDIVEXT_SHIFT 28
39- #define REG_CTRL_CLKDIVEXT_MASK GENMASK(29, 28)
37+ #define REG_CTRL_CLKDIV GENMASK(21, 12)
38+ #define REG_CTRL_CLKDIVEXT GENMASK(29, 28)
39+
40+ #define REG_SLV_ADDR GENMASK(7, 0)
41+ #define REG_SLV_SDA_FILTER GENMASK(10, 8)
42+ #define REG_SLV_SCL_FILTER GENMASK(13, 11)
43+ #define REG_SLV_SCL_LOW GENMASK(27, 16)
44+ #define REG_SLV_SCL_LOW_EN BIT(28)
4045
4146#define I2C_TIMEOUT_MS 500
47+ #define FILTER_DELAY 15
4248
4349enum {
4450TOKEN_END = 0 ,
@@ -133,19 +139,24 @@ static void meson_i2c_set_clk_div(struct meson_i2c *i2c, unsigned int freq)
133139unsigned long clk_rate = clk_get_rate (i2c -> clk );
134140unsignedint div ;
135141
136- div = DIV_ROUND_UP (clk_rate ,freq * i2c -> data -> div_factor );
142+ div = DIV_ROUND_UP (clk_rate ,freq );
143+ div -= FILTER_DELAY ;
144+ div = DIV_ROUND_UP (div ,i2c -> data -> div_factor );
137145
138146/* clock divider has 12 bits */
139- if (div >= ( 1 << 12 )) {
147+ if (div > GENMASK ( 11 , 0 )) {
140148dev_err (i2c -> dev ,"requested bus frequency too low\n" );
141- div = ( 1 << 12 ) - 1 ;
149+ div = GENMASK ( 11 , 0 ) ;
142150}
143151
144- meson_i2c_set_mask (i2c ,REG_CTRL ,REG_CTRL_CLKDIV_MASK ,
145- (div & GENMASK (9 ,0 )) <<REG_CTRL_CLKDIV_SHIFT );
152+ meson_i2c_set_mask (i2c ,REG_CTRL ,REG_CTRL_CLKDIV ,
153+ FIELD_PREP (REG_CTRL_CLKDIV ,div & GENMASK (9 ,0 )));
154+
155+ meson_i2c_set_mask (i2c ,REG_CTRL ,REG_CTRL_CLKDIVEXT ,
156+ FIELD_PREP (REG_CTRL_CLKDIVEXT ,div >>10 ));
146157
147- meson_i2c_set_mask ( i2c , REG_CTRL , REG_CTRL_CLKDIVEXT_MASK ,
148- ( div >> 10 ) << REG_CTRL_CLKDIVEXT_SHIFT );
158+ /* Disable HIGH/LOW mode */
159+ meson_i2c_set_mask ( i2c , REG_SLAVE_ADDR , REG_SLV_SCL_LOW_EN , 0 );
149160
150161dev_dbg (i2c -> dev ,"%s: clk %lu, freq %u, div %u\n" ,__func__ ,
151162clk_rate ,freq ,div );
@@ -280,7 +291,10 @@ static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg)
280291token = (msg -> flags & I2C_M_RD ) ?TOKEN_SLAVE_ADDR_READ :
281292TOKEN_SLAVE_ADDR_WRITE ;
282293
283- writel (msg -> addr <<1 ,i2c -> regs + REG_SLAVE_ADDR );
294+
295+ meson_i2c_set_mask (i2c ,REG_SLAVE_ADDR ,REG_SLV_ADDR ,
296+ FIELD_PREP (REG_SLV_ADDR ,msg -> addr <<1 ));
297+
284298meson_i2c_add_token (i2c ,TOKEN_START );
285299meson_i2c_add_token (i2c ,token );
286300}
@@ -357,16 +371,12 @@ static int meson_i2c_xfer_messages(struct i2c_adapter *adap,
357371struct meson_i2c * i2c = adap -> algo_data ;
358372int i ,ret = 0 ;
359373
360- clk_enable (i2c -> clk );
361-
362374for (i = 0 ;i < num ;i ++ ) {
363375ret = meson_i2c_xfer_msg (i2c ,msgs + i ,i == num - 1 ,atomic );
364376if (ret )
365377break ;
366378}
367379
368- clk_disable (i2c -> clk );
369-
370380return ret ?:i ;
371381}
372382
@@ -435,7 +445,7 @@ static int meson_i2c_probe(struct platform_device *pdev)
435445return ret ;
436446}
437447
438- ret = clk_prepare (i2c -> clk );
448+ ret = clk_prepare_enable (i2c -> clk );
439449if (ret < 0 ) {
440450dev_err (& pdev -> dev ,"can't prepare clock\n" );
441451return ret ;
@@ -457,10 +467,14 @@ static int meson_i2c_probe(struct platform_device *pdev)
457467
458468ret = i2c_add_adapter (& i2c -> adap );
459469if (ret < 0 ) {
460- clk_unprepare (i2c -> clk );
470+ clk_disable_unprepare (i2c -> clk );
461471return ret ;
462472}
463473
474+ /* Disable filtering */
475+ meson_i2c_set_mask (i2c ,REG_SLAVE_ADDR ,
476+ REG_SLV_SDA_FILTER |REG_SLV_SCL_FILTER ,0 );
477+
464478meson_i2c_set_clk_div (i2c ,timings .bus_freq_hz );
465479
466480return 0 ;
@@ -471,7 +485,7 @@ static int meson_i2c_remove(struct platform_device *pdev)
471485struct meson_i2c * i2c = platform_get_drvdata (pdev );
472486
473487i2c_del_adapter (& i2c -> adap );
474- clk_unprepare (i2c -> clk );
488+ clk_disable_unprepare (i2c -> clk );
475489
476490return 0 ;
477491}