aboutsummaryrefslogtreecommitdiff
path: root/sound/i2c/cs8427.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/i2c/cs8427.c')
-rw-r--r--sound/i2c/cs8427.c94
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);