This source file includes following definitions.
- gpioiic_match
- gpioiic_attach
- gpioiic_detach
- gpioiic_i2c_acquire_bus
- gpioiic_i2c_release_bus
- gpioiic_i2c_send_start
- gpioiic_i2c_send_stop
- gpioiic_i2c_initiate_xfer
- gpioiic_i2c_read_byte
- gpioiic_i2c_write_byte
- gpioiic_bb_set_bits
- gpioiic_bb_set_dir
- gpioiic_bb_read_bits
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/device.h>
26 #include <sys/gpio.h>
27 #include <sys/rwlock.h>
28
29 #include <dev/gpio/gpiovar.h>
30
31 #include <dev/i2c/i2cvar.h>
32 #include <dev/i2c/i2c_bitbang.h>
33
34 #define GPIOIIC_PIN_SDA 0
35 #define GPIOIIC_PIN_SCL 1
36 #define GPIOIIC_NPINS 2
37
38 #define GPIOIIC_SDA 0x01
39 #define GPIOIIC_SCL 0x02
40
41 struct gpioiic_softc {
42 struct device sc_dev;
43
44 void * sc_gpio;
45 struct gpio_pinmap sc_map;
46 int __map[GPIOIIC_NPINS];
47
48 struct i2c_controller sc_i2c_tag;
49 struct rwlock sc_i2c_lock;
50
51 int sc_sda;
52 int sc_scl;
53 };
54
55 int gpioiic_match(struct device *, void *, void *);
56 void gpioiic_attach(struct device *, struct device *, void *);
57 int gpioiic_detach(struct device *, int);
58
59 int gpioiic_i2c_acquire_bus(void *, int);
60 void gpioiic_i2c_release_bus(void *, int);
61 int gpioiic_i2c_send_start(void *, int);
62 int gpioiic_i2c_send_stop(void *, int);
63 int gpioiic_i2c_initiate_xfer(void *, i2c_addr_t, int);
64 int gpioiic_i2c_read_byte(void *, u_int8_t *, int);
65 int gpioiic_i2c_write_byte(void *, u_int8_t, int);
66
67 void gpioiic_bb_set_bits(void *, u_int32_t);
68 void gpioiic_bb_set_dir(void *, u_int32_t);
69 u_int32_t gpioiic_bb_read_bits(void *);
70
71 struct cfattach gpioiic_ca = {
72 sizeof(struct gpioiic_softc),
73 gpioiic_match,
74 gpioiic_attach,
75 gpioiic_detach
76 };
77
78 struct cfdriver gpioiic_cd = {
79 NULL, "gpioiic", DV_DULL
80 };
81
82 static const struct i2c_bitbang_ops gpioiic_bbops = {
83 gpioiic_bb_set_bits,
84 gpioiic_bb_set_dir,
85 gpioiic_bb_read_bits,
86 { GPIOIIC_SDA, GPIOIIC_SCL, GPIOIIC_SDA, 0 }
87 };
88
89 int
90 gpioiic_match(struct device *parent, void *match, void *aux)
91 {
92 struct cfdata *cf = match;
93
94 return (strcmp(cf->cf_driver->cd_name, "gpioiic") == 0);
95 }
96
97 void
98 gpioiic_attach(struct device *parent, struct device *self, void *aux)
99 {
100 struct gpioiic_softc *sc = (struct gpioiic_softc *)self;
101 struct gpio_attach_args *ga = aux;
102 struct i2cbus_attach_args iba;
103 int caps;
104
105
106 if (gpio_npins(ga->ga_mask) != GPIOIIC_NPINS) {
107 printf(": invalid pin mask\n");
108 return;
109 }
110
111
112 sc->sc_gpio = ga->ga_gpio;
113 sc->sc_map.pm_map = sc->__map;
114 if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask,
115 &sc->sc_map)) {
116 printf(": can't map pins\n");
117 return;
118 }
119
120
121 caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA);
122 if (!(caps & GPIO_PIN_OUTPUT)) {
123 printf(": SDA pin is unable to drive output\n");
124 goto fail;
125 }
126 if (!(caps & GPIO_PIN_INPUT)) {
127 printf(": SDA pin is unable to read input\n");
128 goto fail;
129 }
130 printf(": SDA[%d]", sc->sc_map.pm_map[GPIOIIC_PIN_SDA]);
131 sc->sc_sda = GPIO_PIN_OUTPUT;
132 if (caps & GPIO_PIN_OPENDRAIN) {
133 printf(" open-drain");
134 sc->sc_sda |= GPIO_PIN_OPENDRAIN;
135 } else if ((caps & GPIO_PIN_PUSHPULL) && (caps & GPIO_PIN_TRISTATE)) {
136 printf(" push-pull tri-state");
137 sc->sc_sda |= GPIO_PIN_PUSHPULL;
138 }
139 if (caps & GPIO_PIN_PULLUP) {
140 printf(" pull-up");
141 sc->sc_sda |= GPIO_PIN_PULLUP;
142 }
143 gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA, sc->sc_sda);
144
145
146 caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SCL);
147 if (!(caps & GPIO_PIN_OUTPUT)) {
148 printf(": SCL pin is unable to drive output\n");
149 goto fail;
150 }
151 printf(", SCL[%d]", sc->sc_map.pm_map[GPIOIIC_PIN_SCL]);
152 sc->sc_scl = GPIO_PIN_OUTPUT;
153 if (caps & GPIO_PIN_OPENDRAIN) {
154 printf(" open-drain");
155 sc->sc_scl |= GPIO_PIN_OPENDRAIN;
156 if (caps & GPIO_PIN_PULLUP) {
157 printf(" pull-up");
158 sc->sc_scl |= GPIO_PIN_PULLUP;
159 }
160 } else if (caps & GPIO_PIN_PUSHPULL) {
161 printf(" push-pull");
162 sc->sc_scl |= GPIO_PIN_PUSHPULL;
163 }
164 gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SCL, sc->sc_scl);
165
166 printf("\n");
167
168
169 rw_init(&sc->sc_i2c_lock, "iiclk");
170 sc->sc_i2c_tag.ic_cookie = sc;
171 sc->sc_i2c_tag.ic_acquire_bus = gpioiic_i2c_acquire_bus;
172 sc->sc_i2c_tag.ic_release_bus = gpioiic_i2c_release_bus;
173 sc->sc_i2c_tag.ic_send_start = gpioiic_i2c_send_start;
174 sc->sc_i2c_tag.ic_send_stop = gpioiic_i2c_send_stop;
175 sc->sc_i2c_tag.ic_initiate_xfer = gpioiic_i2c_initiate_xfer;
176 sc->sc_i2c_tag.ic_read_byte = gpioiic_i2c_read_byte;
177 sc->sc_i2c_tag.ic_write_byte = gpioiic_i2c_write_byte;
178
179 bzero(&iba, sizeof(iba));
180 iba.iba_name = "iic";
181 iba.iba_tag = &sc->sc_i2c_tag;
182 config_found(self, &iba, iicbus_print);
183
184 return;
185
186 fail:
187 gpio_pin_unmap(sc->sc_gpio, &sc->sc_map);
188 }
189
190 int
191 gpioiic_detach(struct device *self, int flags)
192 {
193 return (0);
194 }
195
196 int
197 gpioiic_i2c_acquire_bus(void *cookie, int flags)
198 {
199 struct gpioiic_softc *sc = cookie;
200
201 if (cold || (flags & I2C_F_POLL))
202 return (0);
203
204 return (rw_enter(&sc->sc_i2c_lock, RW_WRITE | RW_INTR));
205 }
206
207 void
208 gpioiic_i2c_release_bus(void *cookie, int flags)
209 {
210 struct gpioiic_softc *sc = cookie;
211
212 if (cold || (flags & I2C_F_POLL))
213 return;
214
215 rw_exit(&sc->sc_i2c_lock);
216 }
217
218 int
219 gpioiic_i2c_send_start(void *cookie, int flags)
220 {
221 return (i2c_bitbang_send_start(cookie, flags, &gpioiic_bbops));
222 }
223
224 int
225 gpioiic_i2c_send_stop(void *cookie, int flags)
226 {
227 return (i2c_bitbang_send_stop(cookie, flags, &gpioiic_bbops));
228 }
229
230 int
231 gpioiic_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
232 {
233 return (i2c_bitbang_initiate_xfer(cookie, addr, flags, &gpioiic_bbops));
234 }
235
236 int
237 gpioiic_i2c_read_byte(void *cookie, u_int8_t *bytep, int flags)
238 {
239 return (i2c_bitbang_read_byte(cookie, bytep, flags, &gpioiic_bbops));
240 }
241
242 int
243 gpioiic_i2c_write_byte(void *cookie, u_int8_t byte, int flags)
244 {
245 return (i2c_bitbang_write_byte(cookie, byte, flags, &gpioiic_bbops));
246 }
247
248 void
249 gpioiic_bb_set_bits(void *cookie, u_int32_t bits)
250 {
251 struct gpioiic_softc *sc = cookie;
252
253 gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA,
254 bits & GPIOIIC_SDA ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
255 gpio_pin_write(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SCL,
256 bits & GPIOIIC_SCL ? GPIO_PIN_HIGH : GPIO_PIN_LOW);
257 }
258
259 void
260 gpioiic_bb_set_dir(void *cookie, u_int32_t bits)
261 {
262 struct gpioiic_softc *sc = cookie;
263 int sda = sc->sc_sda;
264
265 sda &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_TRISTATE);
266 sda |= (bits & GPIOIIC_SDA ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT);
267 if ((sda & GPIO_PIN_PUSHPULL) && !(bits & GPIOIIC_SDA))
268 sda |= GPIO_PIN_TRISTATE;
269 if (sc->sc_sda != sda) {
270 sc->sc_sda = sda;
271 gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, GPIOIIC_PIN_SDA,
272 sc->sc_sda);
273 }
274 }
275
276 u_int32_t
277 gpioiic_bb_read_bits(void *cookie)
278 {
279 struct gpioiic_softc *sc = cookie;
280
281 return (gpio_pin_read(sc->sc_gpio, &sc->sc_map,
282 GPIOIIC_PIN_SDA) == GPIO_PIN_HIGH ? GPIOIIC_SDA : 0);
283 }