1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
6 * Simtec Generic I2C Controller
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/delay.h>
12 #include <linux/platform_device.h>
13 #include <linux/slab.h>
16 #include <linux/i2c.h>
17 #include <linux/i2c-algo-bit.h>
19 struct simtec_i2c_data
{
20 struct resource
*ioarea
;
22 struct i2c_adapter adap
;
23 struct i2c_algo_bit_data bit
;
26 #define CMD_SET_SDA (1<<2)
27 #define CMD_SET_SCL (1<<3)
29 #define STATE_SDA (1<<0)
30 #define STATE_SCL (1<<1)
32 /* i2c bit-bus functions */
34 static void simtec_i2c_setsda(void *pw
, int state
)
36 struct simtec_i2c_data
*pd
= pw
;
37 writeb(CMD_SET_SDA
| (state
? STATE_SDA
: 0), pd
->reg
);
40 static void simtec_i2c_setscl(void *pw
, int state
)
42 struct simtec_i2c_data
*pd
= pw
;
43 writeb(CMD_SET_SCL
| (state
? STATE_SCL
: 0), pd
->reg
);
46 static int simtec_i2c_getsda(void *pw
)
48 struct simtec_i2c_data
*pd
= pw
;
49 return readb(pd
->reg
) & STATE_SDA
? 1 : 0;
52 static int simtec_i2c_getscl(void *pw
)
54 struct simtec_i2c_data
*pd
= pw
;
55 return readb(pd
->reg
) & STATE_SCL
? 1 : 0;
58 /* device registration */
60 static int simtec_i2c_probe(struct platform_device
*dev
)
62 struct simtec_i2c_data
*pd
;
67 pd
= kzalloc(sizeof(struct simtec_i2c_data
), GFP_KERNEL
);
71 platform_set_drvdata(dev
, pd
);
73 res
= platform_get_resource(dev
, IORESOURCE_MEM
, 0);
75 dev_err(&dev
->dev
, "cannot find IO resource\n");
80 size
= resource_size(res
);
82 pd
->ioarea
= request_mem_region(res
->start
, size
, dev
->name
);
83 if (pd
->ioarea
== NULL
) {
84 dev_err(&dev
->dev
, "cannot request IO\n");
89 pd
->reg
= ioremap(res
->start
, size
);
90 if (pd
->reg
== NULL
) {
91 dev_err(&dev
->dev
, "cannot map IO\n");
96 /* setup the private data */
98 pd
->adap
.owner
= THIS_MODULE
;
99 pd
->adap
.algo_data
= &pd
->bit
;
100 pd
->adap
.dev
.parent
= &dev
->dev
;
102 strlcpy(pd
->adap
.name
, "Simtec I2C", sizeof(pd
->adap
.name
));
105 pd
->bit
.setsda
= simtec_i2c_setsda
;
106 pd
->bit
.setscl
= simtec_i2c_setscl
;
107 pd
->bit
.getsda
= simtec_i2c_getsda
;
108 pd
->bit
.getscl
= simtec_i2c_getscl
;
109 pd
->bit
.timeout
= HZ
;
112 ret
= i2c_bit_add_bus(&pd
->adap
);
122 release_mem_region(pd
->ioarea
->start
, size
);
129 static int simtec_i2c_remove(struct platform_device
*dev
)
131 struct simtec_i2c_data
*pd
= platform_get_drvdata(dev
);
133 i2c_del_adapter(&pd
->adap
);
136 release_mem_region(pd
->ioarea
->start
, resource_size(pd
->ioarea
));
144 static struct platform_driver simtec_i2c_driver
= {
146 .name
= "simtec-i2c",
148 .probe
= simtec_i2c_probe
,
149 .remove
= simtec_i2c_remove
,
152 module_platform_driver(simtec_i2c_driver
);
154 MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
155 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
156 MODULE_LICENSE("GPL");
157 MODULE_ALIAS("platform:simtec-i2c");