xref: /OK3568_Linux_fs/kernel/sound/i2c/i2c.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *   Generic i2c interface for ALSA
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
6*4882a593Smuzhiyun  *   Modified for the ALSA driver by Jaroslav Kysela <perex@perex.cz>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/string.h>
13*4882a593Smuzhiyun #include <linux/errno.h>
14*4882a593Smuzhiyun #include <sound/core.h>
15*4882a593Smuzhiyun #include <sound/i2c.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
18*4882a593Smuzhiyun MODULE_DESCRIPTION("Generic i2c interface for ALSA");
19*4882a593Smuzhiyun MODULE_LICENSE("GPL");
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
22*4882a593Smuzhiyun 				 unsigned char *bytes, int count);
23*4882a593Smuzhiyun static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
24*4882a593Smuzhiyun 				 unsigned char *bytes, int count);
25*4882a593Smuzhiyun static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
26*4882a593Smuzhiyun 				 unsigned short addr);
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun static const struct snd_i2c_ops snd_i2c_bit_ops = {
29*4882a593Smuzhiyun 	.sendbytes = snd_i2c_bit_sendbytes,
30*4882a593Smuzhiyun 	.readbytes = snd_i2c_bit_readbytes,
31*4882a593Smuzhiyun 	.probeaddr = snd_i2c_bit_probeaddr,
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
snd_i2c_bus_free(struct snd_i2c_bus * bus)34*4882a593Smuzhiyun static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	struct snd_i2c_bus *slave;
37*4882a593Smuzhiyun 	struct snd_i2c_device *device;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 	if (snd_BUG_ON(!bus))
40*4882a593Smuzhiyun 		return -EINVAL;
41*4882a593Smuzhiyun 	while (!list_empty(&bus->devices)) {
42*4882a593Smuzhiyun 		device = snd_i2c_device(bus->devices.next);
43*4882a593Smuzhiyun 		snd_i2c_device_free(device);
44*4882a593Smuzhiyun 	}
45*4882a593Smuzhiyun 	if (bus->master)
46*4882a593Smuzhiyun 		list_del(&bus->buses);
47*4882a593Smuzhiyun 	else {
48*4882a593Smuzhiyun 		while (!list_empty(&bus->buses)) {
49*4882a593Smuzhiyun 			slave = snd_i2c_slave_bus(bus->buses.next);
50*4882a593Smuzhiyun 			snd_device_free(bus->card, slave);
51*4882a593Smuzhiyun 		}
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 	if (bus->private_free)
54*4882a593Smuzhiyun 		bus->private_free(bus);
55*4882a593Smuzhiyun 	kfree(bus);
56*4882a593Smuzhiyun 	return 0;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
snd_i2c_bus_dev_free(struct snd_device * device)59*4882a593Smuzhiyun static int snd_i2c_bus_dev_free(struct snd_device *device)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	struct snd_i2c_bus *bus = device->device_data;
62*4882a593Smuzhiyun 	return snd_i2c_bus_free(bus);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
snd_i2c_bus_create(struct snd_card * card,const char * name,struct snd_i2c_bus * master,struct snd_i2c_bus ** ri2c)65*4882a593Smuzhiyun int snd_i2c_bus_create(struct snd_card *card, const char *name,
66*4882a593Smuzhiyun 		       struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	struct snd_i2c_bus *bus;
69*4882a593Smuzhiyun 	int err;
70*4882a593Smuzhiyun 	static const struct snd_device_ops ops = {
71*4882a593Smuzhiyun 		.dev_free =	snd_i2c_bus_dev_free,
72*4882a593Smuzhiyun 	};
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	*ri2c = NULL;
75*4882a593Smuzhiyun 	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
76*4882a593Smuzhiyun 	if (bus == NULL)
77*4882a593Smuzhiyun 		return -ENOMEM;
78*4882a593Smuzhiyun 	mutex_init(&bus->lock_mutex);
79*4882a593Smuzhiyun 	INIT_LIST_HEAD(&bus->devices);
80*4882a593Smuzhiyun 	INIT_LIST_HEAD(&bus->buses);
81*4882a593Smuzhiyun 	bus->card = card;
82*4882a593Smuzhiyun 	bus->ops = &snd_i2c_bit_ops;
83*4882a593Smuzhiyun 	if (master) {
84*4882a593Smuzhiyun 		list_add_tail(&bus->buses, &master->buses);
85*4882a593Smuzhiyun 		bus->master = master;
86*4882a593Smuzhiyun 	}
87*4882a593Smuzhiyun 	strlcpy(bus->name, name, sizeof(bus->name));
88*4882a593Smuzhiyun 	err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
89*4882a593Smuzhiyun 	if (err < 0) {
90*4882a593Smuzhiyun 		snd_i2c_bus_free(bus);
91*4882a593Smuzhiyun 		return err;
92*4882a593Smuzhiyun 	}
93*4882a593Smuzhiyun 	*ri2c = bus;
94*4882a593Smuzhiyun 	return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun EXPORT_SYMBOL(snd_i2c_bus_create);
98*4882a593Smuzhiyun 
snd_i2c_device_create(struct snd_i2c_bus * bus,const char * name,unsigned char addr,struct snd_i2c_device ** rdevice)99*4882a593Smuzhiyun int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
100*4882a593Smuzhiyun 			  unsigned char addr, struct snd_i2c_device **rdevice)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	struct snd_i2c_device *device;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	*rdevice = NULL;
105*4882a593Smuzhiyun 	if (snd_BUG_ON(!bus))
106*4882a593Smuzhiyun 		return -EINVAL;
107*4882a593Smuzhiyun 	device = kzalloc(sizeof(*device), GFP_KERNEL);
108*4882a593Smuzhiyun 	if (device == NULL)
109*4882a593Smuzhiyun 		return -ENOMEM;
110*4882a593Smuzhiyun 	device->addr = addr;
111*4882a593Smuzhiyun 	strlcpy(device->name, name, sizeof(device->name));
112*4882a593Smuzhiyun 	list_add_tail(&device->list, &bus->devices);
113*4882a593Smuzhiyun 	device->bus = bus;
114*4882a593Smuzhiyun 	*rdevice = device;
115*4882a593Smuzhiyun 	return 0;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun EXPORT_SYMBOL(snd_i2c_device_create);
119*4882a593Smuzhiyun 
snd_i2c_device_free(struct snd_i2c_device * device)120*4882a593Smuzhiyun int snd_i2c_device_free(struct snd_i2c_device *device)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	if (device->bus)
123*4882a593Smuzhiyun 		list_del(&device->list);
124*4882a593Smuzhiyun 	if (device->private_free)
125*4882a593Smuzhiyun 		device->private_free(device);
126*4882a593Smuzhiyun 	kfree(device);
127*4882a593Smuzhiyun 	return 0;
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun EXPORT_SYMBOL(snd_i2c_device_free);
131*4882a593Smuzhiyun 
snd_i2c_sendbytes(struct snd_i2c_device * device,unsigned char * bytes,int count)132*4882a593Smuzhiyun int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	return device->bus->ops->sendbytes(device, bytes, count);
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun EXPORT_SYMBOL(snd_i2c_sendbytes);
138*4882a593Smuzhiyun 
snd_i2c_readbytes(struct snd_i2c_device * device,unsigned char * bytes,int count)139*4882a593Smuzhiyun int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	return device->bus->ops->readbytes(device, bytes, count);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun EXPORT_SYMBOL(snd_i2c_readbytes);
145*4882a593Smuzhiyun 
snd_i2c_probeaddr(struct snd_i2c_bus * bus,unsigned short addr)146*4882a593Smuzhiyun int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	return bus->ops->probeaddr(bus, addr);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun EXPORT_SYMBOL(snd_i2c_probeaddr);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun  *  bit-operations
155*4882a593Smuzhiyun  */
156*4882a593Smuzhiyun 
snd_i2c_bit_hw_start(struct snd_i2c_bus * bus)157*4882a593Smuzhiyun static inline void snd_i2c_bit_hw_start(struct snd_i2c_bus *bus)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	if (bus->hw_ops.bit->start)
160*4882a593Smuzhiyun 		bus->hw_ops.bit->start(bus);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
snd_i2c_bit_hw_stop(struct snd_i2c_bus * bus)163*4882a593Smuzhiyun static inline void snd_i2c_bit_hw_stop(struct snd_i2c_bus *bus)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	if (bus->hw_ops.bit->stop)
166*4882a593Smuzhiyun 		bus->hw_ops.bit->stop(bus);
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun 
snd_i2c_bit_direction(struct snd_i2c_bus * bus,int clock,int data)169*4882a593Smuzhiyun static void snd_i2c_bit_direction(struct snd_i2c_bus *bus, int clock, int data)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	if (bus->hw_ops.bit->direction)
172*4882a593Smuzhiyun 		bus->hw_ops.bit->direction(bus, clock, data);
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
snd_i2c_bit_set(struct snd_i2c_bus * bus,int clock,int data)175*4882a593Smuzhiyun static void snd_i2c_bit_set(struct snd_i2c_bus *bus, int clock, int data)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	bus->hw_ops.bit->setlines(bus, clock, data);
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun #if 0
181*4882a593Smuzhiyun static int snd_i2c_bit_clock(struct snd_i2c_bus *bus)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	if (bus->hw_ops.bit->getclock)
184*4882a593Smuzhiyun 		return bus->hw_ops.bit->getclock(bus);
185*4882a593Smuzhiyun 	return -ENXIO;
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun #endif
188*4882a593Smuzhiyun 
snd_i2c_bit_data(struct snd_i2c_bus * bus,int ack)189*4882a593Smuzhiyun static int snd_i2c_bit_data(struct snd_i2c_bus *bus, int ack)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	return bus->hw_ops.bit->getdata(bus, ack);
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
snd_i2c_bit_start(struct snd_i2c_bus * bus)194*4882a593Smuzhiyun static void snd_i2c_bit_start(struct snd_i2c_bus *bus)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun 	snd_i2c_bit_hw_start(bus);
197*4882a593Smuzhiyun 	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
198*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 1, 1);
199*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 1, 0);
200*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, 0);
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
snd_i2c_bit_stop(struct snd_i2c_bus * bus)203*4882a593Smuzhiyun static void snd_i2c_bit_stop(struct snd_i2c_bus *bus)
204*4882a593Smuzhiyun {
205*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, 0);
206*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 1, 0);
207*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 1, 1);
208*4882a593Smuzhiyun 	snd_i2c_bit_hw_stop(bus);
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun 
snd_i2c_bit_send(struct snd_i2c_bus * bus,int data)211*4882a593Smuzhiyun static void snd_i2c_bit_send(struct snd_i2c_bus *bus, int data)
212*4882a593Smuzhiyun {
213*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, data);
214*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 1, data);
215*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, data);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
snd_i2c_bit_ack(struct snd_i2c_bus * bus)218*4882a593Smuzhiyun static int snd_i2c_bit_ack(struct snd_i2c_bus *bus)
219*4882a593Smuzhiyun {
220*4882a593Smuzhiyun 	int ack;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, 1);
223*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 1, 1);
224*4882a593Smuzhiyun 	snd_i2c_bit_direction(bus, 1, 0);	/* SCL - wr, SDA - rd */
225*4882a593Smuzhiyun 	ack = snd_i2c_bit_data(bus, 1);
226*4882a593Smuzhiyun 	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
227*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, 1);
228*4882a593Smuzhiyun 	return ack ? -EIO : 0;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun 
snd_i2c_bit_sendbyte(struct snd_i2c_bus * bus,unsigned char data)231*4882a593Smuzhiyun static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	int i, err;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	for (i = 7; i >= 0; i--)
236*4882a593Smuzhiyun 		snd_i2c_bit_send(bus, !!(data & (1 << i)));
237*4882a593Smuzhiyun 	err = snd_i2c_bit_ack(bus);
238*4882a593Smuzhiyun 	if (err < 0)
239*4882a593Smuzhiyun 		return err;
240*4882a593Smuzhiyun 	return 0;
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
snd_i2c_bit_readbyte(struct snd_i2c_bus * bus,int last)243*4882a593Smuzhiyun static int snd_i2c_bit_readbyte(struct snd_i2c_bus *bus, int last)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	int i;
246*4882a593Smuzhiyun 	unsigned char data = 0;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	snd_i2c_bit_set(bus, 0, 1);
249*4882a593Smuzhiyun 	snd_i2c_bit_direction(bus, 1, 0);	/* SCL - wr, SDA - rd */
250*4882a593Smuzhiyun 	for (i = 7; i >= 0; i--) {
251*4882a593Smuzhiyun 		snd_i2c_bit_set(bus, 1, 1);
252*4882a593Smuzhiyun 		if (snd_i2c_bit_data(bus, 0))
253*4882a593Smuzhiyun 			data |= (1 << i);
254*4882a593Smuzhiyun 		snd_i2c_bit_set(bus, 0, 1);
255*4882a593Smuzhiyun 	}
256*4882a593Smuzhiyun 	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
257*4882a593Smuzhiyun 	snd_i2c_bit_send(bus, !!last);
258*4882a593Smuzhiyun 	return data;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun 
snd_i2c_bit_sendbytes(struct snd_i2c_device * device,unsigned char * bytes,int count)261*4882a593Smuzhiyun static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
262*4882a593Smuzhiyun 				 unsigned char *bytes, int count)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	struct snd_i2c_bus *bus = device->bus;
265*4882a593Smuzhiyun 	int err, res = 0;
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	if (device->flags & SND_I2C_DEVICE_ADDRTEN)
268*4882a593Smuzhiyun 		return -EIO;		/* not yet implemented */
269*4882a593Smuzhiyun 	snd_i2c_bit_start(bus);
270*4882a593Smuzhiyun 	err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
271*4882a593Smuzhiyun 	if (err < 0) {
272*4882a593Smuzhiyun 		snd_i2c_bit_hw_stop(bus);
273*4882a593Smuzhiyun 		return err;
274*4882a593Smuzhiyun 	}
275*4882a593Smuzhiyun 	while (count-- > 0) {
276*4882a593Smuzhiyun 		err = snd_i2c_bit_sendbyte(bus, *bytes++);
277*4882a593Smuzhiyun 		if (err < 0) {
278*4882a593Smuzhiyun 			snd_i2c_bit_hw_stop(bus);
279*4882a593Smuzhiyun 			return err;
280*4882a593Smuzhiyun 		}
281*4882a593Smuzhiyun 		res++;
282*4882a593Smuzhiyun 	}
283*4882a593Smuzhiyun 	snd_i2c_bit_stop(bus);
284*4882a593Smuzhiyun 	return res;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
snd_i2c_bit_readbytes(struct snd_i2c_device * device,unsigned char * bytes,int count)287*4882a593Smuzhiyun static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
288*4882a593Smuzhiyun 				 unsigned char *bytes, int count)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun 	struct snd_i2c_bus *bus = device->bus;
291*4882a593Smuzhiyun 	int err, res = 0;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	if (device->flags & SND_I2C_DEVICE_ADDRTEN)
294*4882a593Smuzhiyun 		return -EIO;		/* not yet implemented */
295*4882a593Smuzhiyun 	snd_i2c_bit_start(bus);
296*4882a593Smuzhiyun 	err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
297*4882a593Smuzhiyun 	if (err < 0) {
298*4882a593Smuzhiyun 		snd_i2c_bit_hw_stop(bus);
299*4882a593Smuzhiyun 		return err;
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 	while (count-- > 0) {
302*4882a593Smuzhiyun 		err = snd_i2c_bit_readbyte(bus, count == 0);
303*4882a593Smuzhiyun 		if (err < 0) {
304*4882a593Smuzhiyun 			snd_i2c_bit_hw_stop(bus);
305*4882a593Smuzhiyun 			return err;
306*4882a593Smuzhiyun 		}
307*4882a593Smuzhiyun 		*bytes++ = (unsigned char)err;
308*4882a593Smuzhiyun 		res++;
309*4882a593Smuzhiyun 	}
310*4882a593Smuzhiyun 	snd_i2c_bit_stop(bus);
311*4882a593Smuzhiyun 	return res;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun 
snd_i2c_bit_probeaddr(struct snd_i2c_bus * bus,unsigned short addr)314*4882a593Smuzhiyun static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun 	int err;
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	if (addr & 0x8000)	/* 10-bit address */
319*4882a593Smuzhiyun 		return -EIO;	/* not yet implemented */
320*4882a593Smuzhiyun 	if (addr & 0x7f80)	/* invalid address */
321*4882a593Smuzhiyun 		return -EINVAL;
322*4882a593Smuzhiyun 	snd_i2c_bit_start(bus);
323*4882a593Smuzhiyun 	err = snd_i2c_bit_sendbyte(bus, addr << 1);
324*4882a593Smuzhiyun 	snd_i2c_bit_stop(bus);
325*4882a593Smuzhiyun 	return err;
326*4882a593Smuzhiyun }
327