28 #include <linux/module.h>
29 #include <linux/kernel.h>
32 #include <linux/i2c.h>
43 #define DRV_NAME "i2c-s6000"
45 #define POLL_TIMEOUT (2 * HZ)
65 static inline u16 i2c_rd16(
struct s6i2c_if *iface,
unsigned n)
70 static inline void i2c_wr16(
struct s6i2c_if *iface,
unsigned n,
u16 v)
75 static inline u32 i2c_rd32(
struct s6i2c_if *iface,
unsigned n)
80 static inline void i2c_wr32(
struct s6i2c_if *iface,
unsigned n,
u32 v)
87 static void s6i2c_handle_interrupt(
struct s6i2c_if *iface)
96 dev_err(&iface->
adap.dev,
"s6i2c: spurious I2C irq: %04x\n",
162 spin_lock(&iface->
lock);
164 s6i2c_handle_interrupt(iface);
165 spin_unlock(&iface->
lock);
169 static void s6i2c_timeout(
unsigned long data)
175 s6i2c_handle_interrupt(iface);
183 spin_unlock_irqrestore(&iface->
lock, flags);
197 for (i = 0; i < num; i++) {
200 "s6i2c: 10 bits addr not supported\n");
203 if (msgs[i].len == 0) {
205 "s6i2c: zero length message not supported\n");
210 "s6i2c: multiple xfer cannot change target\n");
247 .master_xfer = s6i2c_master_xfer,
248 .functionality = s6i2c_functionality,
254 if (dividend > 0xffff)
268 if (iface->
irq < 0) {
278 resource_size(iface->
res),
285 resource_size(iface->
res));
293 if (dev->
dev.platform_data) {
296 clock = pdata->
clock;
299 if (IS_ERR(iface->
clk)) {
300 rc = PTR_ERR(iface->
clk);
310 p_adap = &iface->
adap;
312 p_adap->
algo = &s6i2c_algorithm;
316 p_adap->
dev.parent = &dev->
dev;
321 dev_err(&p_adap->
dev,
"s6i2c: can't get IRQ %d\n", iface->
irq);
336 i2c_wr16(iface,
S6_I2C_SSHCNT, nanoseconds_on_clk(iface, 4000));
337 i2c_wr16(iface,
S6_I2C_SSLCNT, nanoseconds_on_clk(iface, 4700));
338 i2c_wr16(iface,
S6_I2C_FSHCNT, nanoseconds_on_clk(iface, 600));
339 i2c_wr16(iface,
S6_I2C_FSLCNT, nanoseconds_on_clk(iface, 1300));
343 platform_set_drvdata(dev, iface);
359 resource_size(iface->
res));
366 struct s6i2c_if *iface = platform_get_drvdata(pdev);
368 platform_set_drvdata(pdev,
NULL);
375 resource_size(iface->
res));
380 .probe = s6i2c_probe,
388 static int __init s6i2c_init(
void)
390 pr_info(
"I2C: S6000 I2C driver\n");
394 static void __exit s6i2c_exit(
void)