aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-sh_mobile.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-sh_mobile.c')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index d2fabd9dbf80..598c49acaeb5 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data {
119 struct i2c_adapter adap; 119 struct i2c_adapter adap;
120 120
121 struct clk *clk; 121 struct clk *clk;
122 u_int8_t icic;
122 u_int8_t iccl; 123 u_int8_t iccl;
123 u_int8_t icch; 124 u_int8_t icch;
125 u_int8_t flags;
124 126
125 spinlock_t lock; 127 spinlock_t lock;
126 wait_queue_head_t wait; 128 wait_queue_head_t wait;
@@ -129,6 +131,8 @@ struct sh_mobile_i2c_data {
129 int sr; 131 int sr;
130}; 132};
131 133
134#define IIC_FLAG_HAS_ICIC67 (1 << 0)
135
132#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */ 136#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
133 137
134/* Register offsets */ 138/* Register offsets */
@@ -155,6 +159,8 @@ struct sh_mobile_i2c_data {
155#define ICSR_WAIT 0x02 159#define ICSR_WAIT 0x02
156#define ICSR_DTE 0x01 160#define ICSR_DTE 0x01
157 161
162#define ICIC_ICCLB8 0x80
163#define ICIC_ICCHB8 0x40
158#define ICIC_ALE 0x08 164#define ICIC_ALE 0x08
159#define ICIC_TACKE 0x04 165#define ICIC_TACKE 0x04
160#define ICIC_WAITE 0x02 166#define ICIC_WAITE 0x02
@@ -162,6 +168,9 @@ struct sh_mobile_i2c_data {
162 168
163static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data) 169static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
164{ 170{
171 if (offs == ICIC)
172 data |= pd->icic;
173
165 iowrite8(data, pd->reg + offs); 174 iowrite8(data, pd->reg + offs);
166} 175}
167 176
@@ -203,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
203 else 212 else
204 pd->iccl = (u_int8_t)(num/denom); 213 pd->iccl = (u_int8_t)(num/denom);
205 214
215 /* one more bit of ICCL in ICIC */
216 if (pd->flags & IIC_FLAG_HAS_ICIC67) {
217 if ((num/denom) > 0xff)
218 pd->icic |= ICIC_ICCLB8;
219 else
220 pd->icic &= ~ICIC_ICCLB8;
221 }
222
206 /* Calculate the value for icch. From the data sheet: 223 /* Calculate the value for icch. From the data sheet:
207 icch = (p clock / transfer rate) * (H / (L + H)) */ 224 icch = (p clock / transfer rate) * (H / (L + H)) */
208 num = i2c_clk * 4; 225 num = i2c_clk * 4;
@@ -212,6 +229,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
212 else 229 else
213 pd->icch = (u_int8_t)(num/denom); 230 pd->icch = (u_int8_t)(num/denom);
214 231
232 /* one more bit of ICCH in ICIC */
233 if (pd->flags & IIC_FLAG_HAS_ICIC67) {
234 if ((num/denom) > 0xff)
235 pd->icic |= ICIC_ICCHB8;
236 else
237 pd->icic &= ~ICIC_ICCHB8;
238 }
239
215 /* Enable channel and configure rx ack */ 240 /* Enable channel and configure rx ack */
216 iic_set_clr(pd, ICCR, ICCR_ICE, 0); 241 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
217 242
@@ -592,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
592 goto err_irq; 617 goto err_irq;
593 } 618 }
594 619
620 /* The IIC blocks on SH-Mobile ARM processors
621 * come with two new bits in ICIC.
622 */
623 if (size > 0x17)
624 pd->flags |= IIC_FLAG_HAS_ICIC67;
625
595 /* Enable Runtime PM for this device. 626 /* Enable Runtime PM for this device.
596 * 627 *
597 * Also tell the Runtime PM core to ignore children 628 * Also tell the Runtime PM core to ignore children