13 #include <linux/i2c.h>
18 #include <linux/slab.h>
20 #include <linux/module.h>
22 #include <asm/clock.h>
69 #define FCR_RFRST 0x02
70 #define FCR_TFRST 0x01
76 #define FIER_TEIE 0x04
77 #define FIER_RXIE 0x02
78 #define FIER_TXIE 0x01
103 static inline void OUT32(
struct cami2c *
cam,
int reg,
unsigned long val)
108 static inline unsigned long IN32(
struct cami2c *
cam,
int reg)
118 unsigned long msr, fsr, fier,
len;
166 if (msg->
len <= len) {
182 while (msg->
len && len) {
241 static void sh7760_i2c_mrecv(
struct cami2c *
id)
249 OUT32(
id,
I2CMAR, (id->
msg->addr << 1) | 1);
255 len =
id->msg->len - 1;
267 static void sh7760_i2c_msend(
struct cami2c *
id)
275 OUT32(
id,
I2CMAR, (id->
msg->addr << 1) | 0);
299 static inline int sh7760_i2c_busy_check(
struct cami2c *
id)
304 static int sh7760_i2c_master_xfer(
struct i2c_adapter *adap,
311 if (sh7760_i2c_busy_check(
id)) {
312 dev_err(&adap->
dev,
"sh7760-i2c%d: bus busy!\n", adap->
nr);
320 id->flags = ((i == (num-1)) ?
IDF_STOP : 0);
326 sh7760_i2c_mrecv(
id);
328 sh7760_i2c_msend(
id);
383 .master_xfer = sh7760_i2c_master_xfer,
384 .functionality = sh7760_i2c_func,
393 static int __devinit calc_CCR(
unsigned long scl_hz)
396 unsigned long mck, m1, dff, odff, iclk;
397 signed char cdf, cdfm;
398 int scgd, scgdm, scgds;
402 return PTR_ERR(mclk);
409 scgdm = cdfm = m1 = 0;
410 for (cdf = 3; cdf >= 0; cdf--) {
411 iclk = mck / (1 + cdf);
412 if (iclk >= 20000000)
414 scgds = ((iclk / scl_hz) - 20) >> 3;
415 for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) {
416 m1 = iclk / (20 + (scgd << 3));
417 dff =
abs(scl_hz - m1);
426 if (odff > (scl_hz >> 2))
430 return ((scgdm << 2) | cdfm);
440 pd = pdev->
dev.platform_data;
449 dev_err(&pdev->
dev,
"no mem for private data\n");
463 dev_err(&pdev->
dev,
"mmio already reserved\n");
477 id->adap.nr = pdev->
id;
478 id->adap.algo = &sh7760_i2c_algo;
480 id->adap.retries = 3;
481 id->adap.algo_data =
id;
482 id->adap.dev.parent = &pdev->
dev;
484 "SH7760 I2C at %08lx", (
unsigned long)res->
start);
500 dev_err(&pdev->
dev,
"invalid SCL clock: %dkHz\n",
515 dev_err(&pdev->
dev,
"reg adap failed: %d\n", ret);
519 platform_set_drvdata(pdev,
id);
541 struct cami2c *
id = platform_get_drvdata(pdev);
549 platform_set_drvdata(pdev,
NULL);
559 .probe = sh7760_i2c_probe,