Deleted Added
full compact
iicbus.c (38775) iicbus.c (40782)
1/*-
2 * Copyright (c) 1998 Nicolas Souchu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1998 Nicolas Souchu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: iicbus.c,v 1.1.2.7 1998/08/29 16:54:16 son Exp $
26 * $Id: iicbus.c,v 1.1.1.1 1998/09/03 20:51:50 nsouch Exp $
27 *
28 */
29
30/*
31 * Autoconfiguration and support routines for the Philips serial I2C bus
32 */
33
34#include <sys/param.h>

--- 14 unchanged lines hidden (view full) ---

49/*
50 * structure used to attach devices to the I2C bus
51 */
52struct iicbus_device {
53 const char *iicd_name; /* device name */
54 int iicd_class; /* driver or slave device class */
55 const char *iicd_desc; /* device descriptor */
56 u_char iicd_addr; /* address of the device */
27 *
28 */
29
30/*
31 * Autoconfiguration and support routines for the Philips serial I2C bus
32 */
33
34#include <sys/param.h>

--- 14 unchanged lines hidden (view full) ---

49/*
50 * structure used to attach devices to the I2C bus
51 */
52struct iicbus_device {
53 const char *iicd_name; /* device name */
54 int iicd_class; /* driver or slave device class */
55 const char *iicd_desc; /* device descriptor */
56 u_char iicd_addr; /* address of the device */
57 int iicd_waitack; /* wait for ack timeout or delay */
57 int iicd_alive; /* 1 if device found */
58};
59
60/*
61 * Common I2C addresses
62 */
63#define I2C_GENERAL_CALL 0x0
58 int iicd_alive; /* 1 if device found */
59};
60
61/*
62 * Common I2C addresses
63 */
64#define I2C_GENERAL_CALL 0x0
64#define I2C_MASTER_ADDRESS 0xaa
65#define I2C_INET_ADDRESS 0xaa
65#define PCF_MASTER_ADDRESS 0xaa
66#define FIRST_SLAVE_ADDR 0x2
66
67#define MAXSLAVE 256
68
69#define IICBUS_UNKNOWN_CLASS 0
70#define IICBUS_DEVICE_CLASS 1
71#define IICBUS_DRIVER_CLASS 2
72
73/*
74 * list of known devices
75 */
76struct iicbus_device iicbus_children[] = {
67
68#define MAXSLAVE 256
69
70#define IICBUS_UNKNOWN_CLASS 0
71#define IICBUS_DEVICE_CLASS 1
72#define IICBUS_DRIVER_CLASS 2
73
74/*
75 * list of known devices
76 */
77struct iicbus_device iicbus_children[] = {
77 { "iic", IICBUS_DRIVER_CLASS, "General Call", I2C_GENERAL_CALL },
78 { "iicsmb", IICBUS_DRIVER_CLASS, "I2C to SMB bridge" },
79 { "iic", IICBUS_DEVICE_CLASS, "PCF8574 I2C to 8 bits parallel i/o", 64},
78 { "iicsmb", IICBUS_DRIVER_CLASS, "I2C to SMB bridge" },
79 { "iic", IICBUS_DEVICE_CLASS, "PCF8574 I2C to 8 bits parallel i/o", 64},
80 { "iic", IICBUS_DEVICE_CLASS, "PCF8584 as slave", I2C_MASTER_ADDRESS },
81 { "ic", IICBUS_DEVICE_CLASS, "network interface", I2C_INET_ADDRESS },
80 { "iic", IICBUS_DEVICE_CLASS, "PCF8584 as slave", PCF_MASTER_ADDRESS },
81 { "ic", IICBUS_DEVICE_CLASS, "network interface", PCF_MASTER_ADDRESS },
82#if 0
83 { "iic", IICBUS_DRIVER_CLASS, "General Call", I2C_GENERAL_CALL },
84#endif
82 { NULL, 0 }
83};
84
85static devclass_t iicbus_devclass;
86
87/*
88 * Device methods
89 */
90static int iicbus_probe(device_t);
91static int iicbus_attach(device_t);
92static void iicbus_print_child(device_t, device_t);
93static int iicbus_read_ivar(device_t , device_t, int, u_long *);
85 { NULL, 0 }
86};
87
88static devclass_t iicbus_devclass;
89
90/*
91 * Device methods
92 */
93static int iicbus_probe(device_t);
94static int iicbus_attach(device_t);
95static void iicbus_print_child(device_t, device_t);
96static int iicbus_read_ivar(device_t , device_t, int, u_long *);
97static int iicbus_write_ivar(device_t , device_t, int, u_long);
94
95static device_method_t iicbus_methods[] = {
96 /* device interface */
97 DEVMETHOD(device_probe, iicbus_probe),
98 DEVMETHOD(device_attach, iicbus_attach),
99 DEVMETHOD(device_detach, bus_generic_detach),
100 DEVMETHOD(device_shutdown, bus_generic_shutdown),
101
102 /* bus interface */
103 DEVMETHOD(bus_print_child, iicbus_print_child),
104 DEVMETHOD(bus_read_ivar, iicbus_read_ivar),
98
99static device_method_t iicbus_methods[] = {
100 /* device interface */
101 DEVMETHOD(device_probe, iicbus_probe),
102 DEVMETHOD(device_attach, iicbus_attach),
103 DEVMETHOD(device_detach, bus_generic_detach),
104 DEVMETHOD(device_shutdown, bus_generic_shutdown),
105
106 /* bus interface */
107 DEVMETHOD(bus_print_child, iicbus_print_child),
108 DEVMETHOD(bus_read_ivar, iicbus_read_ivar),
105 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
109 DEVMETHOD(bus_write_ivar, iicbus_write_ivar),
106 DEVMETHOD(bus_create_intr, bus_generic_create_intr),
107 DEVMETHOD(bus_connect_intr, bus_generic_connect_intr),
108
109 { 0, 0 }
110};
111
112static driver_t iicbus_driver = {
113 "iicbus",
114 iicbus_methods,
115 DRIVER_TYPE_MISC,
116 sizeof(struct iicbus_softc),
117};
118
110 DEVMETHOD(bus_create_intr, bus_generic_create_intr),
111 DEVMETHOD(bus_connect_intr, bus_generic_connect_intr),
112
113 { 0, 0 }
114};
115
116static driver_t iicbus_driver = {
117 "iicbus",
118 iicbus_methods,
119 DRIVER_TYPE_MISC,
120 sizeof(struct iicbus_softc),
121};
122
123static int
124iicbus_probe(device_t dev)
125{
126 /* always present if probed */
127 return (0);
128}
129
130#define MAXADDR 256
131static int iicdev_found[MAXADDR];
132
133static int
134iic_probe_device(device_t dev, u_char addr)
135{
136 int count;
137 char byte;
138
139 if ((addr & 1) == 0) {
140 /* is device writable? */
141 if (!iicbus_start(dev, (u_char)addr, 0)) {
142 iicbus_stop(dev);
143 return (1);
144 }
145 } else {
146 /* is device readable? */
147 if (!iicbus_block_read(dev, (u_char)addr, &byte, 1, &count))
148 return (1);
149 }
150
151 return (0);
152}
153
119/*
154/*
120 * At 'probe' time, we add all the devices which we know about to the
121 * bus. The generic attach routine will probe and attach them if they
122 * are alive.
155 * We add all the devices which we know about.
156 * The generic attach routine will attach them if they are alive.
123 */
124static int
157 */
158static int
125iicbus_probe(device_t dev)
159iicbus_attach(device_t dev)
126{
127 struct iicbus_softc *sc = device_get_softc(dev);
128 struct iicbus_device *iicdev;
129 device_t child;
160{
161 struct iicbus_softc *sc = device_get_softc(dev);
162 struct iicbus_device *iicdev;
163 device_t child;
164 int addr, count;
165 char byte;
130
166
131 /* XXX should query parent */
132 sc->ownaddr = I2C_MASTER_ADDRESS;
167 iicbus_reset(dev, IIC_FASTEST, 0, NULL);
133
168
134 iicbus_reset(dev, IIC_FASTEST);
169 printf("Probing for devices on iicbus%d:", device_get_unit(dev));
135
170
136 for (iicdev = iicbus_children; iicdev->iicd_name; iicdev++) {
171 /* probe any devices */
172 for (addr = FIRST_SLAVE_ADDR; addr < MAXADDR; addr++) {
173 if (iic_probe_device(dev, (u_char)addr)) {
174 printf(" <%x>", addr);
175 }
176 }
177 printf("\n");
137
178
179 /* attach known devices */
180 for (iicdev = iicbus_children; iicdev->iicd_name; iicdev++) {
138 /* probe devices, not drivers */
139 switch (iicdev->iicd_class) {
140 case IICBUS_DEVICE_CLASS:
181 /* probe devices, not drivers */
182 switch (iicdev->iicd_class) {
183 case IICBUS_DEVICE_CLASS:
141 if (!iicbus_start(dev, iicdev->iicd_addr)) {
142 iicbus_stop(dev);
184 if (iic_probe_device(dev, iicdev->iicd_addr))
143 iicdev->iicd_alive = 1;
185 iicdev->iicd_alive = 1;
144 }
145 break;
186 break;
187
146 case IICBUS_DRIVER_CLASS:
188 case IICBUS_DRIVER_CLASS:
147 iicdev->iicd_addr = sc->ownaddr;
189 iicdev->iicd_alive = 1;
148 break;
190 break;
191
149 default:
150 panic("%s: unknown class!", __FUNCTION__);
151 }
152
192 default:
193 panic("%s: unknown class!", __FUNCTION__);
194 }
195
153 child = device_add_child(dev, iicdev->iicd_name, -1, iicdev);
154 device_set_desc(child, iicdev->iicd_desc);
196 if (iicdev->iicd_alive) {
197 child = device_add_child(dev, iicdev->iicd_name,
198 -1, iicdev);
199 device_set_desc(child, iicdev->iicd_desc);
200 }
155 }
201 }
156
157 return (0);
158}
159
160static int
161iicbus_attach(device_t dev)
162{
163 bus_generic_attach(dev);
164
165 return (0);
166}
167
168int
169iicbus_generic_intr(device_t dev, int event, char *buf)
170{
171 return (0);
172}
173
202 bus_generic_attach(dev);
203
204 return (0);
205}
206
207int
208iicbus_generic_intr(device_t dev, int event, char *buf)
209{
210 return (0);
211}
212
213int
214iicbus_null_callback(device_t dev, int index, caddr_t data)
215{
216 return (0);
217}
218
219int
220iicbus_null_repeated_start(device_t dev, u_char addr)
221{
222 return (IIC_ENOTSUPP);
223}
224
174static void
175iicbus_print_child(device_t bus, device_t dev)
176{
177 struct iicbus_device* iicdev = DEVTOIICBUS(dev);
178
179 switch (iicdev->iicd_class) {
180 case IICBUS_DEVICE_CLASS:
225static void
226iicbus_print_child(device_t bus, device_t dev)
227{
228 struct iicbus_device* iicdev = DEVTOIICBUS(dev);
229
230 switch (iicdev->iicd_class) {
231 case IICBUS_DEVICE_CLASS:
181 printf(" on %s%d addr %d %s", device_get_name(bus),
182 device_get_unit(bus), iicdev->iicd_addr,
183 (iicdev->iicd_alive) ? "found" : "not found");
232 printf(" on %s%d addr 0x%x", device_get_name(bus),
233 device_get_unit(bus), iicdev->iicd_addr);
184 break;
185
186 case IICBUS_DRIVER_CLASS:
187 printf(" on %s%d", device_get_name(bus),
188 device_get_unit(bus));
189 break;
190
191 default:

--- 15 unchanged lines hidden (view full) ---

207
208 default:
209 return (ENOENT);
210 }
211
212 return (0);
213}
214
234 break;
235
236 case IICBUS_DRIVER_CLASS:
237 printf(" on %s%d", device_get_name(bus),
238 device_get_unit(bus));
239 break;
240
241 default:

--- 15 unchanged lines hidden (view full) ---

257
258 default:
259 return (ENOENT);
260 }
261
262 return (0);
263}
264
265static int
266iicbus_write_ivar(device_t bus, device_t dev, int index, u_long val)
267{
268 struct iicbus_device* iicdev = DEVTOIICBUS(dev);
269
270 switch (index) {
271 default:
272 return (ENOENT);
273 }
274
275 return (0);
276}
277
215DRIVER_MODULE(iicbus, pcf, iicbus_driver, iicbus_devclass, 0, 0);
278DRIVER_MODULE(iicbus, pcf, iicbus_driver, iicbus_devclass, 0, 0);
279DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0);
280DRIVER_MODULE(iicbus, bti2c, iicbus_driver, iicbus_devclass, 0, 0);