cregit-Linux how code gets into the kernel

Release 4.7 sound/i2c/i2c.c

Directory: sound/i2c
/*
 *   Generic i2c interface for ALSA
 *
 *   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
 *   Modified for the ALSA driver by Jaroslav Kysela <perex@perex.cz>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <sound/core.h>
#include <sound/i2c.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Generic i2c interface for ALSA");
MODULE_LICENSE("GPL");

static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
				 unsigned char *bytes, int count);
static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
				 unsigned char *bytes, int count);
static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
				 unsigned short addr);


static const struct snd_i2c_ops snd_i2c_bit_ops = {
	.sendbytes = snd_i2c_bit_sendbytes,
	.readbytes = snd_i2c_bit_readbytes,
	.probeaddr = snd_i2c_bit_probeaddr,
};


static int snd_i2c_bus_free(struct snd_i2c_bus *bus) { struct snd_i2c_bus *slave; struct snd_i2c_device *device; if (snd_BUG_ON(!bus)) return -EINVAL; while (!list_empty(&bus->devices)) { device = snd_i2c_device(bus->devices.next); snd_i2c_device_free(device); } if (bus->master) list_del(&bus->buses); else { while (!list_empty(&bus->buses)) { slave = snd_i2c_slave_bus(bus->buses.next); snd_device_free(bus->card, slave); } } if (bus->private_free) bus->private_free(bus); kfree(bus); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela11787.97%250.00%
takashi iwaitakashi iwai1612.03%250.00%
Total133100.00%4100.00%


static int snd_i2c_bus_dev_free(struct snd_device *device) { struct snd_i2c_bus *bus = device->device_data; return snd_i2c_bus_free(bus); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela2284.62%266.67%
takashi iwaitakashi iwai415.38%133.33%
Total26100.00%3100.00%


int snd_i2c_bus_create(struct snd_card *card, const char *name, struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c) { struct snd_i2c_bus *bus; int err; static struct snd_device_ops ops = { .dev_free = snd_i2c_bus_dev_free, }; *ri2c = NULL; bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (bus == NULL) return -ENOMEM; mutex_init(&bus->lock_mutex); INIT_LIST_HEAD(&bus->devices); INIT_LIST_HEAD(&bus->buses); bus->card = card; bus->ops = &snd_i2c_bit_ops; if (master) { list_add_tail(&bus->buses, &master->buses); bus->master = master; } strlcpy(bus->name, name, sizeof(bus->name)); err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops); if (err < 0) { snd_i2c_bus_free(bus); return err; } *ri2c = bus; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela17391.05%550.00%
takashi iwaitakashi iwai115.79%220.00%
brian watersbrian waters42.11%110.00%
ben collinsben collins10.53%110.00%
ingo molnaringo molnar10.53%110.00%
Total190100.00%10100.00%

EXPORT_SYMBOL(snd_i2c_bus_create);
int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name, unsigned char addr, struct snd_i2c_device **rdevice) { struct snd_i2c_device *device; *rdevice = NULL; if (snd_BUG_ON(!bus)) return -EINVAL; device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) return -ENOMEM; device->addr = addr; strlcpy(device->name, name, sizeof(device->name)); list_add_tail(&device->list, &bus->devices); device->bus = bus; *rdevice = device; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela10184.87%233.33%
takashi iwaitakashi iwai1714.29%350.00%
ben collinsben collins10.84%116.67%
Total119100.00%6100.00%

EXPORT_SYMBOL(snd_i2c_device_create);
int snd_i2c_device_free(struct snd_i2c_device *device) { if (device->bus) list_del(&device->list); if (device->private_free) device->private_free(device); kfree(device); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela4395.56%266.67%
takashi iwaitakashi iwai24.44%133.33%
Total45100.00%3100.00%

EXPORT_SYMBOL(snd_i2c_device_free);
int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) { return device->bus->ops->sendbytes(device, bytes, count); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela3294.12%150.00%
takashi iwaitakashi iwai25.88%150.00%
Total34100.00%2100.00%

EXPORT_SYMBOL(snd_i2c_sendbytes);
int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) { return device->bus->ops->readbytes(device, bytes, count); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela3294.12%150.00%
takashi iwaitakashi iwai25.88%150.00%
Total34100.00%2100.00%

EXPORT_SYMBOL(snd_i2c_readbytes);
int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr) { return bus->ops->probeaddr(bus, addr); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela2492.31%150.00%
takashi iwaitakashi iwai27.69%150.00%
Total26100.00%2100.00%

EXPORT_SYMBOL(snd_i2c_probeaddr); /* * bit-operations */
static inline void snd_i2c_bit_hw_start(struct snd_i2c_bus *bus) { if (bus->hw_ops.bit->start) bus->hw_ops.bit->start(bus); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela3193.94%150.00%
takashi iwaitakashi iwai26.06%150.00%
Total33100.00%2100.00%


static inline void snd_i2c_bit_hw_stop(struct snd_i2c_bus *bus) { if (bus->hw_ops.bit->stop) bus->hw_ops.bit->stop(bus); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela3193.94%150.00%
takashi iwaitakashi iwai26.06%150.00%
Total33100.00%2100.00%


static void snd_i2c_bit_direction(struct snd_i2c_bus *bus, int clock, int data) { if (bus->hw_ops.bit->direction) bus->hw_ops.bit->direction(bus, clock, data); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela4095.24%150.00%
takashi iwaitakashi iwai24.76%150.00%
Total42100.00%2100.00%


static void snd_i2c_bit_set(struct snd_i2c_bus *bus, int clock, int data) { bus->hw_ops.bit->setlines(bus, clock, data); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela3093.75%150.00%
takashi iwaitakashi iwai26.25%150.00%
Total32100.00%2100.00%

#if 0 static int snd_i2c_bit_clock(struct snd_i2c_bus *bus) { if (bus->hw_ops.bit->getclock) return bus->hw_ops.bit->getclock(bus); return -ENXIO; } #endif
static int snd_i2c_bit_data(struct snd_i2c_bus *bus, int ack) { return bus->hw_ops.bit->getdata(bus, ack); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela2692.86%150.00%
takashi iwaitakashi iwai27.14%150.00%
Total28100.00%2100.00%


static void snd_i2c_bit_start(struct snd_i2c_bus *bus) { snd_i2c_bit_hw_start(bus); snd_i2c_bit_direction(bus, 1, 1); /* SCL - wr, SDA - wr */ snd_i2c_bit_set(bus, 1, 1); snd_i2c_bit_set(bus, 1, 0); snd_i2c_bit_set(bus, 0, 0); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela5196.23%150.00%
takashi iwaitakashi iwai23.77%150.00%
Total53100.00%2100.00%


static void snd_i2c_bit_stop(struct snd_i2c_bus *bus) { snd_i2c_bit_set(bus, 0, 0); snd_i2c_bit_set(bus, 1, 0); snd_i2c_bit_set(bus, 1, 1); snd_i2c_bit_hw_stop(bus); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela4195.35%150.00%
takashi iwaitakashi iwai24.65%150.00%
Total43100.00%2100.00%


static void snd_i2c_bit_send(struct snd_i2c_bus *bus, int data) { snd_i2c_bit_set(bus, 0, data); snd_i2c_bit_set(bus, 1, data); snd_i2c_bit_set(bus, 0, data); }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela3995.12%150.00%
takashi iwaitakashi iwai24.88%150.00%
Total41100.00%2100.00%


static int snd_i2c_bit_ack(struct snd_i2c_bus *bus) { int ack; snd_i2c_bit_set(bus, 0, 1); snd_i2c_bit_set(bus, 1, 1); snd_i2c_bit_direction(bus, 1, 0); /* SCL - wr, SDA - rd */ ack = snd_i2c_bit_data(bus, 1); snd_i2c_bit_direction(bus, 1, 1); /* SCL - wr, SDA - wr */ snd_i2c_bit_set(bus, 0, 1); return ack ? -EIO : 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela7697.44%266.67%
takashi iwaitakashi iwai22.56%133.33%
Total78100.00%3100.00%


static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data) { int i, err; for (i = 7; i >= 0; i--) snd_i2c_bit_send(bus, !!(data & (1 << i))); err = snd_i2c_bit_ack(bus); if (err < 0) return err; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela6391.30%133.33%
brian watersbrian waters45.80%133.33%
takashi iwaitakashi iwai22.90%133.33%
Total69100.00%3100.00%


static int snd_i2c_bit_readbyte(struct snd_i2c_bus *bus, int last) { int i; unsigned char data = 0; snd_i2c_bit_set(bus, 0, 1); snd_i2c_bit_direction(bus, 1, 0); /* SCL - wr, SDA - rd */ for (i = 7; i >= 0; i--) { snd_i2c_bit_set(bus, 1, 1); if (snd_i2c_bit_data(bus, 0)) data |= (1 << i); snd_i2c_bit_set(bus, 0, 1); } snd_i2c_bit_direction(bus, 1, 1); /* SCL - wr, SDA - wr */ snd_i2c_bit_send(bus, !!last); return data; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela11298.25%150.00%
takashi iwaitakashi iwai21.75%150.00%
Total114100.00%2100.00%


static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) { struct snd_i2c_bus *bus = device->bus; int err, res = 0; if (device->flags & SND_I2C_DEVICE_ADDRTEN) return -EIO; /* not yet implemented */ snd_i2c_bit_start(bus); err = snd_i2c_bit_sendbyte(bus, device->addr << 1); if (err < 0) { snd_i2c_bit_hw_stop(bus); return err; } while (count-- > 0) { err = snd_i2c_bit_sendbyte(bus, *bytes++); if (err < 0) { snd_i2c_bit_hw_stop(bus); return err; } res++; } snd_i2c_bit_stop(bus); return res; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela11790.70%250.00%
brian watersbrian waters86.20%125.00%
takashi iwaitakashi iwai43.10%125.00%
Total129100.00%4100.00%


static int snd_i2c_bit_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count) { struct snd_i2c_bus *bus = device->bus; int err, res = 0; if (device->flags & SND_I2C_DEVICE_ADDRTEN) return -EIO; /* not yet implemented */ snd_i2c_bit_start(bus); err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1); if (err < 0) { snd_i2c_bit_hw_stop(bus); return err; } while (count-- > 0) { err = snd_i2c_bit_readbyte(bus, count == 0); if (err < 0) { snd_i2c_bit_hw_stop(bus); return err; } *bytes++ = (unsigned char)err; res++; } snd_i2c_bit_stop(bus); return res; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela13191.61%250.00%
brian watersbrian waters85.59%125.00%
takashi iwaitakashi iwai42.80%125.00%
Total143100.00%4100.00%


static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr) { int err; if (addr & 0x8000) /* 10-bit address */ return -EIO; /* not yet implemented */ if (addr & 0x7f80) /* invalid address */ return -EINVAL; snd_i2c_bit_start(bus); err = snd_i2c_bit_sendbyte(bus, addr << 1); snd_i2c_bit_stop(bus); return err; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela6396.92%266.67%
takashi iwaitakashi iwai23.08%133.33%
Total65100.00%3100.00%


static int __init alsa_i2c_init(void) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela12100.00%1100.00%
Total12100.00%1100.00%


static void __exit alsa_i2c_exit(void) { }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela8100.00%1100.00%
Total8100.00%1100.00%

module_init(alsa_i2c_init) module_exit(alsa_i2c_exit)

Overall Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela152190.27%842.11%
takashi iwaitakashi iwai1277.54%421.05%
brian watersbrian waters241.42%15.26%
david s. millerdavid s. miller60.36%210.53%
paul gortmakerpaul gortmaker30.18%15.26%
ben collinsben collins20.12%15.26%
julia lawalljulia lawall10.06%15.26%
ingo molnaringo molnar10.06%15.26%
Total1685100.00%19100.00%
Directory: sound/i2c
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}