diff options
Diffstat (limited to 'sound/i2c/cs8427.c')
| -rw-r--r-- | sound/i2c/cs8427.c | 94 |
1 files changed, 53 insertions, 41 deletions
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index e57e9cbe6a0..7e21621e492 100644 --- a/sound/i2c/cs8427.c +++ b/sound/i2c/cs8427.c @@ -23,6 +23,9 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/bitrev.h> +#include <linux/module.h> +#include <asm/unaligned.h> #include <sound/core.h> #include <sound/control.h> #include <sound/pcm.h> @@ -54,18 +57,6 @@ struct cs8427 { struct cs8427_stream capture; }; -static unsigned char swapbits(unsigned char val) -{ - int bit; - unsigned char res = 0; - for (bit = 0; bit < 8; bit++) { - res <<= 1; - res |= val & 1; - val >>= 1; - } - return res; -} - int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg, unsigned char val) { @@ -148,7 +139,7 @@ static int snd_cs8427_send_corudata(struct snd_i2c_device *device, } data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF; for (idx = 0; idx < count; idx++) - data[idx + 1] = swapbits(ndata[idx]); + data[idx + 1] = bitrev8(ndata[idx]); if (snd_i2c_sendbytes(device, data, count + 1) != count + 1) return -EIO; return 1; @@ -159,10 +150,8 @@ static void snd_cs8427_free(struct snd_i2c_device *device) kfree(device->private_data); } -int snd_cs8427_create(struct snd_i2c_bus *bus, - unsigned char addr, - unsigned int reset_timeout, - struct snd_i2c_device **r_cs8427) +int snd_cs8427_init(struct snd_i2c_bus *bus, + struct snd_i2c_device *device) { static unsigned char initvals1[] = { CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC, @@ -209,22 +198,10 @@ int snd_cs8427_create(struct snd_i2c_bus *bus, Inhibit E->F transfers. */ CS8427_UD | CS8427_EFTUI | CS8427_DETUI, }; + struct cs8427 *chip = device->private_data; int err; - struct cs8427 *chip; - struct snd_i2c_device *device; unsigned char buf[24]; - if ((err = snd_i2c_device_create(bus, "CS8427", - CS8427_ADDR | (addr & 7), - &device)) < 0) - return err; - chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - snd_i2c_device_free(device); - return -ENOMEM; - } - device->private_free = snd_cs8427_free; - snd_i2c_lock(bus); err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER); if (err != CS8427_VER8427A) { @@ -264,10 +241,7 @@ int snd_cs8427_create(struct snd_i2c_bus *bus, goto __fail; } /* write default channel status bytes */ - buf[0] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 0)); - buf[1] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 8)); - buf[2] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 16)); - buf[3] = ((unsigned char)(SNDRV_PCM_DEFAULT_CON_SPDIF >> 24)); + put_unaligned_le32(SNDRV_PCM_DEFAULT_CON_SPDIF, buf); memset(buf + 4, 0, 24 - 4); if (snd_cs8427_send_corudata(device, 0, buf, 24) < 0) goto __fail; @@ -276,10 +250,44 @@ int snd_cs8427_create(struct snd_i2c_bus *bus, snd_i2c_unlock(bus); /* turn on run bit and rock'n'roll */ + snd_cs8427_reset(device); + + return 0; + +__fail: + snd_i2c_unlock(bus); + + return err; +} +EXPORT_SYMBOL(snd_cs8427_init); + +int snd_cs8427_create(struct snd_i2c_bus *bus, + unsigned char addr, + unsigned int reset_timeout, + struct snd_i2c_device **r_cs8427) +{ + int err; + struct cs8427 *chip; + struct snd_i2c_device *device; + + err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7), + &device); + if (err < 0) + return err; + chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + snd_i2c_device_free(device); + return -ENOMEM; + } + device->private_free = snd_cs8427_free; + if (reset_timeout < 1) reset_timeout = 1; chip->reset_timeout = reset_timeout; - snd_cs8427_reset(device); + + err = snd_cs8427_init(bus, device); + if (err) + goto __fail; #if 0 // it's nice for read tests { @@ -298,7 +306,6 @@ int snd_cs8427_create(struct snd_i2c_bus *bus, return 0; __fail: - snd_i2c_unlock(bus); snd_i2c_device_free(device); return err < 0 ? err : -EIO; } @@ -316,7 +323,8 @@ static void snd_cs8427_reset(struct snd_i2c_device *cs8427) unsigned long end_time; int data, aes3input = 0; - snd_assert(cs8427, return); + if (snd_BUG_ON(!cs8427)) + return; chip = cs8427->private_data; snd_i2c_lock(cs8427->bus); if ((chip->regmap[CS8427_REG_CLOCKSOURCE] & CS8427_RXDAES3INPUT) == @@ -528,7 +536,8 @@ int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427, unsigned int idx; int err; - snd_assert(play_substream && cap_substream, return -EINVAL); + if (snd_BUG_ON(!play_substream || !cap_substream)) + return -EINVAL; for (idx = 0; idx < ARRAY_SIZE(snd_cs8427_iec958_controls); idx++) { kctl = snd_ctl_new1(&snd_cs8427_iec958_controls[idx], cs8427); if (kctl == NULL) @@ -545,7 +554,8 @@ int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427, chip->playback.substream = play_substream; chip->capture.substream = cap_substream; - snd_assert(chip->playback.pcm_ctl, return -EIO); + if (snd_BUG_ON(!chip->playback.pcm_ctl)) + return -EIO; return 0; } @@ -555,7 +565,8 @@ int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active) { struct cs8427 *chip; - snd_assert(cs8427, return -ENXIO); + if (snd_BUG_ON(!cs8427)) + return -ENXIO; chip = cs8427->private_data; if (active) memcpy(chip->playback.pcm_status, @@ -575,7 +586,8 @@ int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate) char *status; int err, reset; - snd_assert(cs8427, return -ENXIO); + if (snd_BUG_ON(!cs8427)) + return -ENXIO; chip = cs8427->private_data; status = chip->playback.pcm_status; snd_i2c_lock(cs8427->bus); |
