Ejemplo n.º 1
0
/*
 * change the input clock selection
 * spdif_clock = 1 - IEC958 input, 0 - Envy24
 */
static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif_clock)
{
	unsigned char reg[2] = { 0x80 | 4, 0 };   /* CS8427 auto increment | register number 4 + data */
	unsigned char val, nval;
	int res = 0;

	snd_i2c_lock(ice->i2c);
	if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
	if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) {
		snd_i2c_unlock(ice->i2c);
		return -EIO;
	}
	nval = val & 0xf0;
	if (spdif_clock)
		nval |= 0x01;
	else
		nval |= 0x04;
	if (val != nval) {
		reg[1] = nval;
		if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) {
			res = -EIO;
		} else {
			res++;
		}
	}
	snd_i2c_unlock(ice->i2c);
	return res;
}
Ejemplo n.º 2
0
static int pt2258_switch_put(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pt2258 *pt = kcontrol->private_data;
	unsigned char bytes[2];
	int val;

	val = !ucontrol->value.integer.value[0];
	if (pt->mute == val)
		return 0;

	pt->mute = val;
	bytes[0] = val ? PT2258_CMD_MUTE : PT2258_CMD_UNMUTE;
	snd_i2c_lock(pt->i2c_bus);
	if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1)
		goto __error;
	snd_i2c_unlock(pt->i2c_bus);

	return 1;

      __error:
	snd_i2c_unlock(pt->i2c_bus);
	snd_printk(KERN_ERR "PT2258 access failed 2\n");
	return -EIO;
}
Ejemplo n.º 3
0
static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
				    int udata,
				    unsigned char *ndata,
				    int count)
{
	struct cs8427 *chip = device->private_data;
	char *hw_data = udata ?
		chip->playback.hw_udata : chip->playback.hw_status;
	char data[32];
	int err, idx;

	if (!memcmp(hw_data, ndata, count))
		return 0;
	if ((err = snd_cs8427_select_corudata(device, udata)) < 0)
		return err;
	memcpy(hw_data, ndata, count);
	if (udata) {
		memset(data, 0, sizeof(data));
		if (memcmp(hw_data, data, count) == 0) {
			chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;
			chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS |
				CS8427_EFTUI;
			err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,
						   chip->regmap[CS8427_REG_UDATABUF]);
			return err < 0 ? err : 0;
		}
	}
	data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
	for (idx = 0; idx < count; idx++)
		data[idx + 1] = bitrev8(ndata[idx]);
	if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
		return -EIO;
	return 1;
}
Ejemplo n.º 4
0
static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_value *ucontrol)
{
	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
	int change, count, err;
	unsigned char bytes[3];
	unsigned char val1, val2;
	
	val1 = (ucontrol->value.integer.value[0] % 44) + 0x14;
	val2 = (ucontrol->value.integer.value[1] % 44) + 0x14;
	snd_i2c_lock(tea->bus);
	change = val1 != tea->mleft || val2 != tea->mright;
	tea->mleft = val1;
	tea->mright = val2;
	count = 0;
	if (tea->regs[TEA6330T_SADDR_VOLUME_LEFT] != 0) {
		bytes[count++] = TEA6330T_SADDR_VOLUME_LEFT;
		bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = tea->mleft;
	}
	if (tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] != 0) {
		if (count == 0)
			bytes[count++] = TEA6330T_SADDR_VOLUME_RIGHT;
		bytes[count++] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = tea->mright;
	}
	if (count > 0) {
		if ((err = snd_i2c_sendbytes(tea->device, bytes, count)) < 0)
			change = err;
	}
	snd_i2c_unlock(tea->bus);
	return change;
}
Ejemplo n.º 5
0
static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol,
			 struct snd_ctl_elem_value *ucontrol)
{
	char reg = 0x10; /* CS8427 receiver error register */
	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);

	if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1)
		snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
	snd_i2c_readbytes(ice->cs8427, &reg, 1);
	ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0;
	return 0;
}
Ejemplo n.º 6
0
int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned char val)
{
	int err;
	unsigned char buf[2];

	buf[0] = reg & 0x7f;
	buf[1] = val;
	if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
		snd_printk("unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
		return err < 0 ? err : -EIO;
	}
	return 0;
}
Ejemplo n.º 7
0
static int pt2258_stereo_volume_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
	struct snd_pt2258 *pt = kcontrol->private_data;
	int base = kcontrol->private_value;
	unsigned char bytes[2];
	int val0, val1;

	val0 = 79 - ucontrol->value.integer.value[0];
	val1 = 79 - ucontrol->value.integer.value[1];
	if (val0 < 0 || val0 > 79 || val1 < 0 || val1 > 79)
		return -EINVAL;
	if (val0 == pt->volume[base] && val1 == pt->volume[base + 1])
		return 0;

	pt->volume[base] = val0;
	bytes[0] = pt2258_channel_code[2 * base] | (val0 / 10);
	bytes[1] = pt2258_channel_code[2 * base + 1] | (val0 % 10);
	snd_i2c_lock(pt->i2c_bus);
	if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2)
		goto __error;
	snd_i2c_unlock(pt->i2c_bus);

	pt->volume[base + 1] = val1;
	bytes[0] = pt2258_channel_code[2 * base + 2] | (val1 / 10);
	bytes[1] = pt2258_channel_code[2 * base + 3] | (val1 % 10);
	snd_i2c_lock(pt->i2c_bus);
	if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2)
		goto __error;
	snd_i2c_unlock(pt->i2c_bus);

	return 1;

      __error:
	snd_i2c_unlock(pt->i2c_bus);
	snd_printk(KERN_ERR "PT2258 access failed\n");
	return -EIO;
}
Ejemplo n.º 8
0
int snd_pt2258_reset(struct snd_pt2258 *pt)
{
	unsigned char bytes[2];
	int i;

	/*            */
	bytes[0] = PT2258_CMD_RESET;
	snd_i2c_lock(pt->i2c_bus);
	if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1)
		goto __error;
	snd_i2c_unlock(pt->i2c_bus);

	/*                   */
	pt->mute = 1;
	bytes[0] = PT2258_CMD_MUTE;
	snd_i2c_lock(pt->i2c_bus);
	if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 1) != 1)
		goto __error;
	snd_i2c_unlock(pt->i2c_bus);

	/*                         */
	for (i = 0; i < 6; ++i)
		pt->volume[i] = 0;
	bytes[0] = 0xd0;
	bytes[1] = 0xe0;
	snd_i2c_lock(pt->i2c_bus);
	if (snd_i2c_sendbytes(pt->i2c_dev, bytes, 2) != 2)
		goto __error;
	snd_i2c_unlock(pt->i2c_bus);

	return 0;

      __error:
	snd_i2c_unlock(pt->i2c_bus);
	snd_printk(KERN_ERR "PT2258 reset failed\n");
	return -EIO;
}
Ejemplo n.º 9
0
int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg)
{
	int err;
	unsigned char buf;

	if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
		snd_printk("unable to send register 0x%x byte to CS8427\n", reg);
		return err < 0 ? err : -EIO;
	}
	if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
		snd_printk("unable to read register 0x%x byte from CS8427\n", reg);
		return err < 0 ? err : -EIO;
	}
	return buf;
}
Ejemplo n.º 10
0
static int snd_tea6330t_put_treble(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
	int change, err;
	unsigned char bytes[2];
	unsigned char val1;
	
	val1 = ucontrol->value.integer.value[0] % (tea->max_treble + 1);
	snd_i2c_lock(tea->bus);
	tea->treble = val1;
	val1 += 3;
	change = tea->regs[TEA6330T_SADDR_TREBLE] != val1;
	bytes[0] = TEA6330T_SADDR_TREBLE;
	bytes[1] = tea->regs[TEA6330T_SADDR_TREBLE] = val1;
	if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
		change = err;
	snd_i2c_unlock(tea->bus);
	return change;
}
Ejemplo n.º 11
0
static int snd_tea6330t_put_bass(struct snd_kcontrol *kcontrol,
				 struct snd_ctl_elem_value *ucontrol)
{
	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
	int change, err;
	unsigned char bytes[2];
	unsigned char val1;
	
	val1 = ucontrol->value.integer.value[0] % (tea->max_bass + 1);
	snd_i2c_lock(tea->bus);
	tea->bass = val1;
	val1 += tea->equalizer ? 7 : 3;
	change = tea->regs[TEA6330T_SADDR_BASS] != val1;
	bytes[0] = TEA6330T_SADDR_BASS;
	bytes[1] = tea->regs[TEA6330T_SADDR_BASS] = val1;
	if ((err = snd_i2c_sendbytes(tea->device, bytes, 2)) < 0)
		change = err;
	snd_i2c_unlock(tea->bus);
	return change;
}
Ejemplo n.º 12
0
static int snd_tea6330t_put_master_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
{
	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
	int change, err;
	unsigned char bytes[3];
	unsigned char oval1, oval2, val1, val2;
	
	val1 = ucontrol->value.integer.value[0] & 1;
	val2 = ucontrol->value.integer.value[1] & 1;
	snd_i2c_lock(tea->bus);
	oval1 = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1;
	oval2 = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] == 0 ? 0 : 1;
	change = val1 != oval1 || val2 != oval2;
	tea->regs[TEA6330T_SADDR_VOLUME_LEFT] = val1 ? tea->mleft : 0;
	tea->regs[TEA6330T_SADDR_VOLUME_RIGHT] = val2 ? tea->mright : 0;
	bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
	bytes[1] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT];
	bytes[2] = tea->regs[TEA6330T_SADDR_VOLUME_RIGHT];
	if ((err = snd_i2c_sendbytes(tea->device, bytes, 3)) < 0)
		change = err;
	snd_i2c_unlock(tea->bus);
	return change;
}
Ejemplo n.º 13
0
static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
	unsigned char reg = CS8427_REG_QSUBCODE;
	int err;

	snd_i2c_lock(device->bus);
	if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
		snd_printk(KERN_ERR "unable to send register 0x%x byte "
			   "to CS8427\n", reg);
		snd_i2c_unlock(device->bus);
		return err < 0 ? err : -EIO;
	}
	err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10);
	if (err != 10) {
		snd_printk(KERN_ERR "unable to read Q-subcode bytes "
			   "from CS8427\n");
		snd_i2c_unlock(device->bus);
		return err < 0 ? err : -EIO;
	}
	snd_i2c_unlock(device->bus);
	return 0;
}
Ejemplo n.º 14
0
int snd_cs8427_create(struct snd_i2c_bus *bus,
		      unsigned char addr,
		      unsigned int reset_timeout,
		      struct snd_i2c_device **r_cs8427)
{
	static unsigned char initvals1[] = {
	  CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
	  /* CS8427_REG_CONTROL1: RMCK to OMCK, valid PCM audio, disable mutes,
	     TCBL=output */
	  CS8427_SWCLK | CS8427_TCBLDIR,
	  /* CS8427_REG_CONTROL2: hold last valid audio sample, RMCK=256*Fs,
	     normal stereo operation */
	  0x00,
	  /* CS8427_REG_DATAFLOW: output drivers normal operation, Tx<=serial,
	     Rx=>serial */
	  CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,
	  /* CS8427_REG_CLOCKSOURCE: Run off, CMCK=256*Fs,
	     output time base = OMCK, input time base = recovered input clock,
	     recovered input clock source is ILRCK changed to AES3INPUT
	     (workaround, see snd_cs8427_reset) */
	  CS8427_RXDILRCK,
	  /* CS8427_REG_SERIALINPUT: Serial audio input port data format = I2S,
	     24-bit, 64*Fsi */
	  CS8427_SIDEL | CS8427_SILRPOL,
	  /* CS8427_REG_SERIALOUTPUT: Serial audio output port data format
	     = I2S, 24-bit, 64*Fsi */
	  CS8427_SODEL | CS8427_SOLRPOL,
	};
	static unsigned char initvals2[] = {
	  CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,
	  /* CS8427_REG_RECVERRMASK: unmask the input PLL clock, V, confidence,
	     biphase, parity status bits */
	  /* CS8427_UNLOCK | CS8427_V | CS8427_CONF | CS8427_BIP | CS8427_PAR,*/
	  0xff, /* set everything */
	  /* CS8427_REG_CSDATABUF:
	     Registers 32-55 window to CS buffer
	     Inhibit D->E transfers from overwriting first 5 bytes of CS data.
	     Inhibit D->E transfers (all) of CS data.
	     Allow E->F transfer of CS data.
	     One byte mode; both A/B channels get same written CB data.
	     A channel info is output to chip's EMPH* pin. */
	  CS8427_CBMR | CS8427_DETCI,
	  /* CS8427_REG_UDATABUF:
	     Use internal buffer to transmit User (U) data.
	     Chip's U pin is an output.
	     Transmit all O's for user data.
	     Inhibit D->E transfers.
	     Inhibit E->F transfers. */
	  CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
	};
	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) {
		/* give second chance */
#ifdef CONFIG_DEBUG_PRINTK
		snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
			   "let me try again...\n", err);
#else
		;
#endif
		err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
	}
	if (err != CS8427_VER8427A) {
		snd_i2c_unlock(bus);
		snd_printk(KERN_ERR "unable to find CS8427 signature "
			   "(expected 0x%x, read 0x%x),\n",
			   CS8427_VER8427A, err);
		snd_printk(KERN_ERR "   initialization is not completed\n");
		return -EFAULT;
	}
	/* turn off run bit while making changes to configuration */
	err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);
	if (err < 0)
		goto __fail;
	/* send initial values */
	memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
	if ((err = snd_i2c_sendbytes(device, initvals1, 7)) != 7) {
		err = err < 0 ? err : -EIO;
		goto __fail;
	}
	/* Turn off CS8427 interrupt stuff that is not used in hardware */
	memset(buf, 0, 7);
	/* from address 9 to 15 */
	buf[0] = 9;	/* register */
	if ((err = snd_i2c_sendbytes(device, buf, 7)) != 7)
		goto __fail;
	/* send transfer initialization sequence */
	memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
	if ((err = snd_i2c_sendbytes(device, initvals2, 4)) != 4) {
		err = err < 0 ? err : -EIO;
		goto __fail;
	}
	/* write default channel status bytes */
	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;
	memcpy(chip->playback.def_status, buf, 24);
	memcpy(chip->playback.pcm_status, buf, 24);
	snd_i2c_unlock(bus);

	/* turn on run bit and rock'n'roll */
	if (reset_timeout < 1)
		reset_timeout = 1;
	chip->reset_timeout = reset_timeout;
	snd_cs8427_reset(device);

#if 0	// it's nice for read tests
	{
	char buf[128];
	int xx;
	buf[0] = 0x81;
	snd_i2c_sendbytes(device, buf, 1);
	snd_i2c_readbytes(device, buf, 127);
	for (xx = 0; xx < 127; xx++)
#ifdef CONFIG_DEBUG_PRINTK
		printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
#else
		;
#endif
	}
#endif
	
	if (r_cs8427)
		*r_cs8427 = device;
	return 0;

      __fail:
      	snd_i2c_unlock(bus);
      	snd_i2c_device_free(device);
      	return err < 0 ? err : -EIO;
}
Ejemplo n.º 15
0
int snd_tea6330t_update_mixer(struct snd_card *card,
			      struct snd_i2c_bus *bus,
			      int equalizer, int fader)
{
	struct snd_i2c_device *device;
	struct tea6330t *tea;
	struct snd_kcontrol_new *knew;
	unsigned int idx;
	int err = -ENOMEM;
	u8 default_treble, default_bass;
	unsigned char bytes[7];

	tea = kzalloc(sizeof(*tea), GFP_KERNEL);
	if (tea == NULL)
		return -ENOMEM;
	if ((err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device)) < 0) {
		kfree(tea);
		return err;
	}
	tea->device = device;
	tea->bus = bus;
	tea->equalizer = equalizer;
	tea->fader = fader;
	device->private_data = tea;
	device->private_free = snd_tea6330_free;

	snd_i2c_lock(bus);

	/* turn fader off and handle equalizer */
	tea->regs[TEA6330T_SADDR_FADER] = 0x3f;
	tea->regs[TEA6330T_SADDR_AUDIO_SWITCH] = equalizer ? 0 : TEA6330T_EQN;
	/* initialize mixer */
	if (!tea->equalizer) {
		tea->max_bass = 9;
		tea->max_treble = 8;
		default_bass = 3 + 4;
		tea->bass = 4;
		default_treble = 3 + 4;
		tea->treble = 4;
	} else {
		tea->max_bass = 5;
		tea->max_treble = 0;
		default_bass = 7 + 4;
		tea->bass = 4;
		default_treble = 3;
		tea->treble = 0;
	}
	tea->mleft = tea->mright = 0x14;
	tea->regs[TEA6330T_SADDR_BASS] = default_bass;
	tea->regs[TEA6330T_SADDR_TREBLE] = default_treble;

	/* compose I2C message and put the hardware to initial state */
	bytes[0] = TEA6330T_SADDR_VOLUME_LEFT;
	for (idx = 0; idx < 6; idx++)
		bytes[idx+1] = tea->regs[idx];
	if ((err = snd_i2c_sendbytes(device, bytes, 7)) < 0)
		goto __error;

	strcat(card->mixername, ",TEA6330T");
	if ((err = snd_component_add(card, "TEA6330T")) < 0)
		goto __error;

	for (idx = 0; idx < ARRAY_SIZE(snd_tea6330t_controls); idx++) {
		knew = &snd_tea6330t_controls[idx];
		if (tea->treble == 0 && !strcmp(knew->name, "Tone Control - Treble"))
			continue;
		if ((err = snd_ctl_add(card, snd_ctl_new1(knew, tea))) < 0)
			goto __error;
	}

	snd_i2c_unlock(bus);
	return 0;
	
      __error:
      	snd_i2c_unlock(bus);
      	snd_i2c_device_free(device);
      	return err;
}
Ejemplo n.º 16
0
int snd_cs8427_create(struct snd_i2c_bus *bus,
		      unsigned char addr,
		      unsigned int reset_timeout,
		      struct snd_i2c_device **r_cs8427)
{
	static unsigned char initvals1[] = {
	  CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
	  /*                                                                   
                  */
	  CS8427_SWCLK | CS8427_TCBLDIR,
	  /*                                                                
                              */
	  0x00,
	  /*                                                                  
                 */
	  CS8427_TXDSERIAL | CS8427_SPDAES3RECEIVER,
	  /*                                              
                                                                       
                                                                
                                         */
	  CS8427_RXDILRCK,
	  /*                                                                   
                     */
	  CS8427_SIDEL | CS8427_SILRPOL,
	  /*                                                              
                            */
	  CS8427_SODEL | CS8427_SOLRPOL,
	};
	static unsigned char initvals2[] = {
	  CS8427_REG_RECVERRMASK | CS8427_REG_AUTOINC,
	  /*                                                                   
                                  */
	  /*                                                                  */
	  0xff, /*                */
	  /*                      
                                         
                                                                       
                                              
                                     
                                                                
                                                    */
	  CS8427_CBMR | CS8427_DETCI,
	  /*                     
                                                    
                                
                                     
                             
                              */
	  CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
	};
	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) {
		/*                    */
		snd_printk(KERN_WARNING "invalid CS8427 signature 0x%x: "
			   "let me try again...\n", err);
		err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER);
	}
	if (err != CS8427_VER8427A) {
		snd_i2c_unlock(bus);
		snd_printk(KERN_ERR "unable to find CS8427 signature "
			   "(expected 0x%x, read 0x%x),\n",
			   CS8427_VER8427A, err);
		snd_printk(KERN_ERR "   initialization is not completed\n");
		return -EFAULT;
	}
	/*                                                        */
	err = snd_cs8427_reg_write(device, CS8427_REG_CLOCKSOURCE, 0x00);
	if (err < 0)
		goto __fail;
	/*                     */
	memcpy(chip->regmap + (initvals1[0] & 0x7f), initvals1 + 1, 6);
	if ((err = snd_i2c_sendbytes(device, initvals1, 7)) != 7) {
		err = err < 0 ? err : -EIO;
		goto __fail;
	}
	/*                                                              */
	memset(buf, 0, 7);
	/*                      */
	buf[0] = 9;	/*          */
	if ((err = snd_i2c_sendbytes(device, buf, 7)) != 7)
		goto __fail;
	/*                                       */
	memcpy(chip->regmap + (initvals2[0] & 0x7f), initvals2 + 1, 3);
	if ((err = snd_i2c_sendbytes(device, initvals2, 4)) != 4) {
		err = err < 0 ? err : -EIO;
		goto __fail;
	}
	/*                                    */
	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;
	memcpy(chip->playback.def_status, buf, 24);
	memcpy(chip->playback.pcm_status, buf, 24);
	snd_i2c_unlock(bus);

	/*                                 */
	if (reset_timeout < 1)
		reset_timeout = 1;
	chip->reset_timeout = reset_timeout;
	snd_cs8427_reset(device);

#if 0	//                         
	{
	char buf[128];
	int xx;
	buf[0] = 0x81;
	snd_i2c_sendbytes(device, buf, 1);
	snd_i2c_readbytes(device, buf, 127);
	for (xx = 0; xx < 127; xx++)
		printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
	}
#endif
	
	if (r_cs8427)
		*r_cs8427 = device;
	return 0;

      __fail:
      	snd_i2c_unlock(bus);
      	snd_i2c_device_free(device);
      	return err < 0 ? err : -EIO;
}