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.c121
1 files changed, 84 insertions, 37 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index ffb405d7c6f..598c49acaeb 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,15 +131,17 @@ 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 */
135#define ICDR(pd) (pd->reg + 0x00) 139#define ICDR 0x00
136#define ICCR(pd) (pd->reg + 0x04) 140#define ICCR 0x04
137#define ICSR(pd) (pd->reg + 0x08) 141#define ICSR 0x08
138#define ICIC(pd) (pd->reg + 0x0c) 142#define ICIC 0x0c
139#define ICCL(pd) (pd->reg + 0x10) 143#define ICCL 0x10
140#define ICCH(pd) (pd->reg + 0x14) 144#define ICCH 0x14
141 145
142/* Register bits */ 146/* Register bits */
143#define ICCR_ICE 0x80 147#define ICCR_ICE 0x80
@@ -155,11 +159,32 @@ 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
161#define ICIC_DTEE 0x01 167#define ICIC_DTEE 0x01
162 168
169static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
170{
171 if (offs == ICIC)
172 data |= pd->icic;
173
174 iowrite8(data, pd->reg + offs);
175}
176
177static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs)
178{
179 return ioread8(pd->reg + offs);
180}
181
182static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
183 unsigned char set, unsigned char clr)
184{
185 iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
186}
187
163static void activate_ch(struct sh_mobile_i2c_data *pd) 188static void activate_ch(struct sh_mobile_i2c_data *pd)
164{ 189{
165 unsigned long i2c_clk; 190 unsigned long i2c_clk;
@@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
187 else 212 else
188 pd->iccl = (u_int8_t)(num/denom); 213 pd->iccl = (u_int8_t)(num/denom);
189 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
190 /* Calculate the value for icch. From the data sheet: 223 /* Calculate the value for icch. From the data sheet:
191 icch = (p clock / transfer rate) * (H / (L + H)) */ 224 icch = (p clock / transfer rate) * (H / (L + H)) */
192 num = i2c_clk * 4; 225 num = i2c_clk * 4;
@@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
196 else 229 else
197 pd->icch = (u_int8_t)(num/denom); 230 pd->icch = (u_int8_t)(num/denom);
198 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
199 /* Enable channel and configure rx ack */ 240 /* Enable channel and configure rx ack */
200 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); 241 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
201 242
202 /* Mask all interrupts */ 243 /* Mask all interrupts */
203 iowrite8(0, ICIC(pd)); 244 iic_wr(pd, ICIC, 0);
204 245
205 /* Set the clock */ 246 /* Set the clock */
206 iowrite8(pd->iccl, ICCL(pd)); 247 iic_wr(pd, ICCL, pd->iccl);
207 iowrite8(pd->icch, ICCH(pd)); 248 iic_wr(pd, ICCH, pd->icch);
208} 249}
209 250
210static void deactivate_ch(struct sh_mobile_i2c_data *pd) 251static void deactivate_ch(struct sh_mobile_i2c_data *pd)
211{ 252{
212 /* Clear/disable interrupts */ 253 /* Clear/disable interrupts */
213 iowrite8(0, ICSR(pd)); 254 iic_wr(pd, ICSR, 0);
214 iowrite8(0, ICIC(pd)); 255 iic_wr(pd, ICIC, 0);
215 256
216 /* Disable channel */ 257 /* Disable channel */
217 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); 258 iic_set_clr(pd, ICCR, 0, ICCR_ICE);
218 259
219 /* Disable clock and mark device as idle */ 260 /* Disable clock and mark device as idle */
220 clk_disable(pd->clk); 261 clk_disable(pd->clk);
@@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
233 274
234 switch (op) { 275 switch (op) {
235 case OP_START: /* issue start and trigger DTE interrupt */ 276 case OP_START: /* issue start and trigger DTE interrupt */
236 iowrite8(0x94, ICCR(pd)); 277 iic_wr(pd, ICCR, 0x94);
237 break; 278 break;
238 case OP_TX_FIRST: /* disable DTE interrupt and write data */ 279 case OP_TX_FIRST: /* disable DTE interrupt and write data */
239 iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd)); 280 iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
240 iowrite8(data, ICDR(pd)); 281 iic_wr(pd, ICDR, data);
241 break; 282 break;
242 case OP_TX: /* write data */ 283 case OP_TX: /* write data */
243 iowrite8(data, ICDR(pd)); 284 iic_wr(pd, ICDR, data);
244 break; 285 break;
245 case OP_TX_STOP: /* write data and issue a stop afterwards */ 286 case OP_TX_STOP: /* write data and issue a stop afterwards */
246 iowrite8(data, ICDR(pd)); 287 iic_wr(pd, ICDR, data);
247 iowrite8(0x90, ICCR(pd)); 288 iic_wr(pd, ICCR, 0x90);
248 break; 289 break;
249 case OP_TX_TO_RX: /* select read mode */ 290 case OP_TX_TO_RX: /* select read mode */
250 iowrite8(0x81, ICCR(pd)); 291 iic_wr(pd, ICCR, 0x81);
251 break; 292 break;
252 case OP_RX: /* just read data */ 293 case OP_RX: /* just read data */
253 ret = ioread8(ICDR(pd)); 294 ret = iic_rd(pd, ICDR);
254 break; 295 break;
255 case OP_RX_STOP: /* enable DTE interrupt, issue stop */ 296 case OP_RX_STOP: /* enable DTE interrupt, issue stop */
256 iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, 297 iic_wr(pd, ICIC,
257 ICIC(pd)); 298 ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
258 iowrite8(0xc0, ICCR(pd)); 299 iic_wr(pd, ICCR, 0xc0);
259 break; 300 break;
260 case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ 301 case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */
261 iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE, 302 iic_wr(pd, ICIC,
262 ICIC(pd)); 303 ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
263 ret = ioread8(ICDR(pd)); 304 ret = iic_rd(pd, ICDR);
264 iowrite8(0xc0, ICCR(pd)); 305 iic_wr(pd, ICCR, 0xc0);
265 break; 306 break;
266 } 307 }
267 308
@@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
367 unsigned char sr; 408 unsigned char sr;
368 int wakeup; 409 int wakeup;
369 410
370 sr = ioread8(ICSR(pd)); 411 sr = iic_rd(pd, ICSR);
371 pd->sr |= sr; /* remember state */ 412 pd->sr |= sr; /* remember state */
372 413
373 dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr, 414 dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
@@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
376 417
377 if (sr & (ICSR_AL | ICSR_TACK)) { 418 if (sr & (ICSR_AL | ICSR_TACK)) {
378 /* don't interrupt transaction - continue to issue stop */ 419 /* don't interrupt transaction - continue to issue stop */
379 iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd)); 420 iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK));
380 wakeup = 0; 421 wakeup = 0;
381 } else if (pd->msg->flags & I2C_M_RD) 422 } else if (pd->msg->flags & I2C_M_RD)
382 wakeup = sh_mobile_i2c_isr_rx(pd); 423 wakeup = sh_mobile_i2c_isr_rx(pd);
@@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
384 wakeup = sh_mobile_i2c_isr_tx(pd); 425 wakeup = sh_mobile_i2c_isr_tx(pd);
385 426
386 if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */ 427 if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */
387 iowrite8(sr & ~ICSR_WAIT, ICSR(pd)); 428 iic_wr(pd, ICSR, sr & ~ICSR_WAIT);
388 429
389 if (wakeup) { 430 if (wakeup) {
390 pd->sr |= SW_DONE; 431 pd->sr |= SW_DONE;
@@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
402 } 443 }
403 444
404 /* Initialize channel registers */ 445 /* Initialize channel registers */
405 iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd)); 446 iic_set_clr(pd, ICCR, 0, ICCR_ICE);
406 447
407 /* Enable channel and configure rx ack */ 448 /* Enable channel and configure rx ack */
408 iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd)); 449 iic_set_clr(pd, ICCR, ICCR_ICE, 0);
409 450
410 /* Set the clock */ 451 /* Set the clock */
411 iowrite8(pd->iccl, ICCL(pd)); 452 iic_wr(pd, ICCL, pd->iccl);
412 iowrite8(pd->icch, ICCH(pd)); 453 iic_wr(pd, ICCH, pd->icch);
413 454
414 pd->msg = usr_msg; 455 pd->msg = usr_msg;
415 pd->pos = -1; 456 pd->pos = -1;
416 pd->sr = 0; 457 pd->sr = 0;
417 458
418 /* Enable all interrupts to begin with */ 459 /* Enable all interrupts to begin with */
419 iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd)); 460 iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
420 return 0; 461 return 0;
421} 462}
422 463
@@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
451 492
452 retry_count = 1000; 493 retry_count = 1000;
453again: 494again:
454 val = ioread8(ICSR(pd)); 495 val = iic_rd(pd, ICSR);
455 496
456 dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); 497 dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
457 498
@@ -576,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
576 goto err_irq; 617 goto err_irq;
577 } 618 }
578 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
579 /* Enable Runtime PM for this device. 626 /* Enable Runtime PM for this device.
580 * 627 *
581 * Also tell the Runtime PM core to ignore children 628 * Also tell the Runtime PM core to ignore children