Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 25268
b: refs/heads/master
c: af9b70a
h: refs/heads/master
v: v3
  • Loading branch information
Maximilian Rehkopf authored and Jaroslav Kysela committed Mar 31, 2006
1 parent 1cb6fea commit 3e285c1
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0bd43b5bc9e61e9dc48ad5ee68737316e5d94b60
refs/heads/master: af9b70ac0044d126b28d28894cd890447c0a9dc1
163 changes: 160 additions & 3 deletions trunk/sound/pci/ice1712/aureon.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,151 @@
#define CS8415_C_BUFFER 0x20
#define CS8415_ID 0x7F

static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, unsigned short val) {
/* PCA9554 registers */
#define PCA9554_DEV 0x40 /* I2C device address */
#define PCA9554_IN 0x00 /* input port */
#define PCA9554_OUT 0x01 /* output port */
#define PCA9554_INVERT 0x02 /* input invert */
#define PCA9554_DIR 0x03 /* port directions */

/*
* Aureon Universe additional controls using PCA9554
*/

/*
* Send data to pca9554
*/
static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg,
unsigned char data)
{
unsigned int tmp;
int i, j;
unsigned char dev = PCA9554_DEV; /* ID 0100000, write */
unsigned char val = 0;

tmp = snd_ice1712_gpio_read(ice);

snd_ice1712_gpio_set_mask(ice, ~(AUREON_SPI_MOSI|AUREON_SPI_CLK|
AUREON_WM_RW|AUREON_WM_CS|
AUREON_CS8415_CS));
tmp |= AUREON_WM_RW;
tmp |= AUREON_CS8415_CS | AUREON_WM_CS; /* disable SPI devices */

tmp &= ~AUREON_SPI_MOSI;
tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(50);

/*
* send i2c stop condition and start condition
* to obtain sane state
*/
tmp |= AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(50);
tmp |= AUREON_SPI_MOSI;
snd_ice1712_gpio_write(ice, tmp);
udelay(100);
tmp &= ~AUREON_SPI_MOSI;
snd_ice1712_gpio_write(ice, tmp);
udelay(50);
tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(100);
/*
* send device address, command and value,
* skipping ack cycles inbetween
*/
for (j = 0; j < 3; j++) {
switch(j) {
case 0: val = dev; break;
case 1: val = reg; break;
case 2: val = data; break;
}
for (i = 7; i >= 0; i--) {
tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
if (val & (1 << i))
tmp |= AUREON_SPI_MOSI;
else
tmp &= ~AUREON_SPI_MOSI;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
tmp |= AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
}
tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
tmp |= AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
}
tmp &= ~AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
tmp &= ~AUREON_SPI_MOSI;
snd_ice1712_gpio_write(ice, tmp);
udelay(40);
tmp |= AUREON_SPI_CLK;
snd_ice1712_gpio_write(ice, tmp);
udelay(50);
tmp |= AUREON_SPI_MOSI;
snd_ice1712_gpio_write(ice, tmp);
udelay(100);
}

static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
char *texts[3] = {"Internal Aux", "Wavetable", "Rear Line-In"};

uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->count = 1;
uinfo->value.enumerated.items = 3;
if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
return 0;
}

static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out;
return 0;
}

static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
unsigned char oval, nval;
int change;

snd_ice1712_save_gpio_status(ice);

oval = ice->spec.aureon.pca9554_out;
nval = ucontrol->value.integer.value[0];
if ((change = (oval != nval))) {
aureon_pca9554_write(ice, PCA9554_OUT, nval);
ice->spec.aureon.pca9554_out = nval;
}
snd_ice1712_restore_gpio_status(ice);

return change;
}


static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
unsigned short val)
{
unsigned int tmp;

/* Send address to XILINX chip */
Expand Down Expand Up @@ -146,7 +290,8 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
/*
* Initialize STAC9744 chip
*/
static int aureon_ac97_init (struct snd_ice1712 *ice) {
static int aureon_ac97_init (struct snd_ice1712 *ice)
{
int i;
static unsigned short ac97_defaults[] = {
0x00, 0x9640,
Expand Down Expand Up @@ -1598,7 +1743,15 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
.get = aureon_ac97_vol_get,
.put = aureon_ac97_vol_put,
.private_value = AC97_VIDEO|AUREON_AC97_STEREO
}
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Aux Source",
.info = aureon_universe_inmux_info,
.get = aureon_universe_inmux_get,
.put = aureon_universe_inmux_put
}

};


Expand Down Expand Up @@ -1856,6 +2009,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
}

snd_ice1712_restore_gpio_status(ice);

/* initialize PCA9554 pin directions & set default input*/
aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */

ice->spec.aureon.master[0] = WM_VOL_MUTE;
ice->spec.aureon.master[1] = WM_VOL_MUTE;
Expand Down
1 change: 1 addition & 0 deletions trunk/sound/pci/ice1712/ice1712.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ struct snd_ice1712 {
unsigned int cs8415_mux;
unsigned short master[2];
unsigned short vol[8];
unsigned char pca9554_out;
} aureon;
/* AC97 register cache for Phase28 */
struct phase28_spec {
Expand Down

0 comments on commit 3e285c1

Please sign in to comment.