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