linux/sound/i2c/i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *   Generic i2c interface for ALSA
   4 *
   5 *   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
   6 *   Modified for the ALSA driver by Jaroslav Kysela <perex@perex.cz>
   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
  17MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
  18MODULE_DESCRIPTION("Generic i2c interface for ALSA");
  19MODULE_LICENSE("GPL");
  20
  21static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
  22                                 unsigned char *bytes, int count);
  23static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
  24                                 unsigned char *bytes, int count);
  25static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
  26                                 unsigned short addr);
  27
  28static 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
  34static 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
  59static 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
  65int 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
  97EXPORT_SYMBOL(snd_i2c_bus_create);
  98
  99int 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
 118EXPORT_SYMBOL(snd_i2c_device_create);
 119
 120int 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
 130EXPORT_SYMBOL(snd_i2c_device_free);
 131
 132int 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
 137EXPORT_SYMBOL(snd_i2c_sendbytes);
 138
 139int 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
 144EXPORT_SYMBOL(snd_i2c_readbytes);
 145
 146int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
 147{
 148        return bus->ops->probeaddr(bus, addr);
 149}
 150
 151EXPORT_SYMBOL(snd_i2c_probeaddr);
 152
 153/*
 154 *  bit-operations
 155 */
 156
 157static 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
 163static 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
 169static 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
 175static 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
 181static 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
 189static int snd_i2c_bit_data(struct snd_i2c_bus *bus, int ack)
 190{
 191        return bus->hw_ops.bit->getdata(bus, ack);
 192}
 193
 194static 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
 203static 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
 211static 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
 218static 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
 231static 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
 243static 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
 261static 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
 287static 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
 314static 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