linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc: Fix PowerMac sound i2c
@ 2006-01-08  4:52 Benjamin Herrenschmidt
  2006-01-08  4:55 ` Hollis Blanchard
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2006-01-08  4:52 UTC (permalink / raw)
  To: linuxppc-dev list, linuxppc64-dev

My patch reworking the PowerMac i2c code break the sound drivers as they
used to rely on some broken behaviour of i2c-keywest that is gone now.
This patch should fix them (tested on a g5 with alsa only). It might
also fix an oops if the alsa driver hits an unsupported chip.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Index: linux-work/sound/ppc/tumbler.c
===================================================================
--- linux-work.orig/sound/ppc/tumbler.c	2005-11-24 17:19:14.000000000 +1100
+++ linux-work/sound/ppc/tumbler.c	2006-01-08 15:18:09.000000000 +1100
@@ -137,6 +137,22 @@ static int send_init_client(pmac_keywest
 	return 0;
 }
 
+static int tumbler_write_block(struct i2c_client *client, u8 reg, int len,
+			       u8 *values)
+{
+        union i2c_smbus_data data;
+        int err;
+
+        data.block[0] = len;
+	memcpy(&data.block[1], values, len);
+        err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                             I2C_SMBUS_WRITE, reg, I2C_SMBUS_I2C_BLOCK_DATA,
+                             &data);
+        return err;
+}
+
+
+
 
 static int tumbler_init_client(pmac_keywest_t *i2c)
 {
@@ -239,8 +255,7 @@ static int tumbler_set_master_volume(pma
 	block[4] = (right_vol >> 8)  & 0xff;
 	block[5] = (right_vol >> 0)  & 0xff;
   
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
-				       6, block) < 0) {
+	if (tumbler_write_block(mix->i2c.client, TAS_REG_VOL, 6, block) < 0) {
 		snd_printk("failed to set volume \n");
 		return -EINVAL;
 	}
@@ -340,8 +355,7 @@ static int tumbler_set_drc(pmac_tumbler_
 		val[1] = 0;
 	}
 
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-				       2, val) < 0) {
+	if (tumbler_write_block(mix->i2c.client, TAS_REG_DRC, 2, val) < 0) {
 		snd_printk("failed to set DRC\n");
 		return -EINVAL;
 	}
@@ -376,8 +390,7 @@ static int snapper_set_drc(pmac_tumbler_
 	val[4] = 0x60;
 	val[5] = 0xa0;
 
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-				       6, val) < 0) {
+	if (tumbler_write_block(mix->i2c.client, TAS_REG_DRC, 6, val) < 0) {
 		snd_printk("failed to set DRC\n");
 		return -EINVAL;
 	}
@@ -481,8 +494,8 @@ static int tumbler_set_mono_volume(pmac_
 	vol = info->table[vol];
 	for (i = 0; i < info->bytes; i++)
 		block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
-	if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
-				       info->bytes, block) < 0) {
+	if (tumbler_write_block(mix->i2c.client, info->reg,
+				  info->bytes, block) < 0) {
 		snd_printk("failed to set mono volume %d\n", info->index);
 		return -EINVAL;
 	}
@@ -611,7 +624,7 @@ static int snapper_set_mix_vol1(pmac_tum
 		for (j = 0; j < 3; j++)
 			block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
 	}
-	if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
+	if (tumbler_write_block(mix->i2c.client, reg, 9, block) < 0) {
 		snd_printk("failed to set mono volume %d\n", reg);
 		return -EINVAL;
 	}
Index: linux-work/sound/oss/dmasound/tas_common.h
===================================================================
--- linux-work.orig/sound/oss/dmasound/tas_common.h	2005-11-24 17:19:14.000000000 +1100
+++ linux-work/sound/oss/dmasound/tas_common.h	2006-01-08 15:33:29.000000000 +1100
@@ -157,6 +157,21 @@ tas_mono_to_stereo(uint mono)
 	return mono | (mono<<8);
 }
 
+static int tas_write_block(struct i2c_client *client, u8 reg, int len, u8 *vals)
+{
+        union i2c_smbus_data data;
+        int err;
+
+        data.block[0] = len;
+	memcpy(&data.block[1], vals, len);
+        err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
+                             I2C_SMBUS_WRITE, reg, I2C_SMBUS_I2C_BLOCK_DATA,
+                             &data);
+        return err;
+}
+
+
+
 /*
  * Todo: make these functions a bit more efficient !
  */
@@ -178,10 +193,8 @@ tas_write_register(	struct tas_data_t *s
 	if (write_mode & WRITE_SHADOW)
 		memcpy(self->shadow[reg_num],data,reg_width);
 	if (write_mode & WRITE_HW) {
-		rc=i2c_smbus_write_block_data(self->client,
-					      reg_num,
-					      reg_width,
-					      data);
+		rc = tas_write_block(self->client, reg_num,
+				     reg_width, data);
 		if (rc < 0) {
 			printk("tas: I2C block write failed \n");  
 			return rc; 
@@ -199,10 +212,8 @@ tas_sync_register(	struct tas_data_t *se
 
 	if (reg_width==0 || self==NULL)
 		return -EINVAL;
-	rc=i2c_smbus_write_block_data(self->client,
-				      reg_num,
-				      reg_width,
-				      self->shadow[reg_num]);
+	rc = tas_write_block(self->client, reg_num,
+			     reg_width, self->shadow[reg_num]);
 	if (rc < 0) {
 		printk("tas: I2C block write failed \n");
 		return rc;
Index: linux-work/sound/ppc/pmac.c
===================================================================
--- linux-work.orig/sound/ppc/pmac.c	2005-12-19 16:13:48.000000000 +1100
+++ linux-work/sound/ppc/pmac.c	2006-01-08 15:37:10.000000000 +1100
@@ -74,7 +74,7 @@ static int snd_pmac_dbdma_alloc(pmac_t *
 
 static void snd_pmac_dbdma_free(pmac_t *chip, pmac_dbdma_t *rec)
 {
-	if (rec) {
+	if (rec->space) {
 		unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
 
 		dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
@@ -895,6 +895,7 @@ static int __init snd_pmac_detect(pmac_t
 	chip->can_capture = 1;
 	chip->num_freqs = ARRAY_SIZE(awacs_freqs);
 	chip->freq_table = awacs_freqs;
+	chip->pdev = NULL;
 
 	chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08  4:52 [PATCH] powerpc: Fix PowerMac sound i2c Benjamin Herrenschmidt
@ 2006-01-08  4:55 ` Hollis Blanchard
  2006-01-08  6:22   ` Benjamin Herrenschmidt
  2006-01-08 10:37 ` Andreas Schwab
  2006-02-04 18:26 ` Paul Collins
  2 siblings, 1 reply; 9+ messages in thread
From: Hollis Blanchard @ 2006-01-08  4:55 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc64-dev, linuxppc-dev list

On Jan 7, 2006, at 10:52 PM, Benjamin Herrenschmidt wrote:

> +        data.block[0] = len;
> +	memcpy(&data.block[1], values, len);

Seem to be mixing tabs and spaces here (in both *_write_block 
functions).

-Hollis

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08  4:55 ` Hollis Blanchard
@ 2006-01-08  6:22   ` Benjamin Herrenschmidt
  2006-01-08 23:37     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2006-01-08  6:22 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: linuxppc64-dev, linuxppc-dev list

On Sat, 2006-01-07 at 22:55 -0600, Hollis Blanchard wrote:
> On Jan 7, 2006, at 10:52 PM, Benjamin Herrenschmidt wrote:
> 
> > +        data.block[0] = len;
> > +	memcpy(&data.block[1], values, len);
> 
> Seem to be mixing tabs and spaces here (in both *_write_block 
> functions).

You mean the patch got mangled or the code is mixing tab/spaces ? I
think the driver was pretty mixed up in the first place, I'll have to
check.

Ben.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08  4:52 [PATCH] powerpc: Fix PowerMac sound i2c Benjamin Herrenschmidt
  2006-01-08  4:55 ` Hollis Blanchard
@ 2006-01-08 10:37 ` Andreas Schwab
  2006-01-08 13:30   ` Andreas Schwab
  2006-01-08 21:03   ` Benjamin Herrenschmidt
  2006-02-04 18:26 ` Paul Collins
  2 siblings, 2 replies; 9+ messages in thread
From: Andreas Schwab @ 2006-01-08 10:37 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, linuxppc64-dev

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> My patch reworking the PowerMac i2c code break the sound drivers as they
> used to rely on some broken behaviour of i2c-keywest that is gone now.

I'm not sure, but from looking at the other i2c drivers I'd rather think
that the old behaviour of i2c-keywest was correct.  There are only a few
that implement both I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_I2C_BLOCK_DATA, but
none of them write the length byte together with the data.  The commands
are ony different in behaviour when reading: with I2C_SMBUS_I2C_BLOCK_DATA
a fixed sized block is read from the bus, whereas with
I2C_SMBUS_BLOCK_DATA the size of the block is variable.  At least that's
how i2c-nforce2, i2c-viapro and i2c-amd8111 implement the commands.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08 10:37 ` Andreas Schwab
@ 2006-01-08 13:30   ` Andreas Schwab
  2006-01-08 21:03   ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 9+ messages in thread
From: Andreas Schwab @ 2006-01-08 13:30 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, linuxppc64-dev

Andreas Schwab <schwab@suse.de> writes:

> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
>
>> My patch reworking the PowerMac i2c code break the sound drivers as they
>> used to rely on some broken behaviour of i2c-keywest that is gone now.
>
> I'm not sure, but from looking at the other i2c drivers I'd rather think
> that the old behaviour of i2c-keywest was correct.

I have now read the thread on linux-kernel@ and I have to revise my
opinion.  I think I now understand better the difference between smbus and
i2c bus.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08 10:37 ` Andreas Schwab
  2006-01-08 13:30   ` Andreas Schwab
@ 2006-01-08 21:03   ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2006-01-08 21:03 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev list, linuxppc64-dev

On Sun, 2006-01-08 at 11:37 +0100, Andreas Schwab wrote:
> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> 
> > My patch reworking the PowerMac i2c code break the sound drivers as they
> > used to rely on some broken behaviour of i2c-keywest that is gone now.
> 
> I'm not sure, but from looking at the other i2c drivers I'd rather think
> that the old behaviour of i2c-keywest was correct.  There are only a few
> that implement both I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_I2C_BLOCK_DATA, but
> none of them write the length byte together with the data.  The commands
> are ony different in behaviour when reading: with I2C_SMBUS_I2C_BLOCK_DATA
> a fixed sized block is read from the bus, whereas with
> I2C_SMBUS_BLOCK_DATA the size of the block is variable.  At least that's
> how i2c-nforce2, i2c-viapro and i2c-amd8111 implement the commands.

They are probably all wrong :) Look at the fallback implementation of
smbus using base i2c in i2c-core.c .. I also checked the smbus spec and
indeed, an smbus block transfer has the lenght on the wire.

Ben

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08  6:22   ` Benjamin Herrenschmidt
@ 2006-01-08 23:37     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2006-01-08 23:37 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: linuxppc64-dev, linuxppc-dev list

Ok, here's another version that uses the proper wrapper in the i2c
layer, that was removed but is coming back...

Index: linux-work/sound/ppc/tumbler.c
===================================================================
--- linux-work.orig/sound/ppc/tumbler.c	2006-01-09 10:29:54.000000000 +1100
+++ linux-work/sound/ppc/tumbler.c	2006-01-09 10:30:14.000000000 +1100
@@ -137,7 +137,6 @@ static int send_init_client(pmac_keywest
 	return 0;
 }
 
-
 static int tumbler_init_client(pmac_keywest_t *i2c)
 {
 	static unsigned int regs[] = {
@@ -239,8 +238,8 @@ static int tumbler_set_master_volume(pma
 	block[4] = (right_vol >> 8)  & 0xff;
 	block[5] = (right_vol >> 0)  & 0xff;
   
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
-				       6, block) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6,
+					   block) < 0) {
 		snd_printk("failed to set volume \n");
 		return -EINVAL;
 	}
@@ -340,8 +339,8 @@ static int tumbler_set_drc(pmac_tumbler_
 		val[1] = 0;
 	}
 
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-				       2, val) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+					   2, val) < 0) {
 		snd_printk("failed to set DRC\n");
 		return -EINVAL;
 	}
@@ -376,8 +375,8 @@ static int snapper_set_drc(pmac_tumbler_
 	val[4] = 0x60;
 	val[5] = 0xa0;
 
-	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
-				       6, val) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC,
+					   6, val) < 0) {
 		snd_printk("failed to set DRC\n");
 		return -EINVAL;
 	}
@@ -481,8 +480,8 @@ static int tumbler_set_mono_volume(pmac_
 	vol = info->table[vol];
 	for (i = 0; i < info->bytes; i++)
 		block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
-	if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
-				       info->bytes, block) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg,
+					   info->bytes, block) < 0) {
 		snd_printk("failed to set mono volume %d\n", info->index);
 		return -EINVAL;
 	}
@@ -611,7 +610,8 @@ static int snapper_set_mix_vol1(pmac_tum
 		for (j = 0; j < 3; j++)
 			block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
 	}
-	if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
+	if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg,
+					   9, block) < 0) {
 		snd_printk("failed to set mono volume %d\n", reg);
 		return -EINVAL;
 	}
Index: linux-work/sound/ppc/pmac.c
===================================================================
--- linux-work.orig/sound/ppc/pmac.c	2006-01-09 10:29:54.000000000 +1100
+++ linux-work/sound/ppc/pmac.c	2006-01-09 10:30:14.000000000 +1100
@@ -74,7 +74,7 @@ static int snd_pmac_dbdma_alloc(pmac_t *
 
 static void snd_pmac_dbdma_free(pmac_t *chip, pmac_dbdma_t *rec)
 {
-	if (rec) {
+	if (rec->space) {
 		unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
 
 		dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
@@ -895,6 +895,7 @@ static int __init snd_pmac_detect(pmac_t
 	chip->can_capture = 1;
 	chip->num_freqs = ARRAY_SIZE(awacs_freqs);
 	chip->freq_table = awacs_freqs;
+	chip->pdev = NULL;
 
 	chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
 
Index: linux-work/sound/oss/dmasound/tas_common.h
===================================================================
--- linux-work.orig/sound/oss/dmasound/tas_common.h	2006-01-09 10:29:54.000000000 +1100
+++ linux-work/sound/oss/dmasound/tas_common.h	2006-01-09 10:31:09.000000000 +1100
@@ -178,10 +178,10 @@ tas_write_register(	struct tas_data_t *s
 	if (write_mode & WRITE_SHADOW)
 		memcpy(self->shadow[reg_num],data,reg_width);
 	if (write_mode & WRITE_HW) {
-		rc=i2c_smbus_write_block_data(self->client,
-					      reg_num,
-					      reg_width,
-					      data);
+		rc=i2c_smbus_write_i2c_block_data(self->client,
+						  reg_num,
+						  reg_width,
+						  data);
 		if (rc < 0) {
 			printk("tas: I2C block write failed \n");  
 			return rc; 
@@ -199,10 +199,10 @@ tas_sync_register(	struct tas_data_t *se
 
 	if (reg_width==0 || self==NULL)
 		return -EINVAL;
-	rc=i2c_smbus_write_block_data(self->client,
-				      reg_num,
-				      reg_width,
-				      self->shadow[reg_num]);
+	rc=i2c_smbus_write_i2c_block_data(self->client,
+					  reg_num,
+					  reg_width,
+					  self->shadow[reg_num]);
 	if (rc < 0) {
 		printk("tas: I2C block write failed \n");
 		return rc;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-01-08  4:52 [PATCH] powerpc: Fix PowerMac sound i2c Benjamin Herrenschmidt
  2006-01-08  4:55 ` Hollis Blanchard
  2006-01-08 10:37 ` Andreas Schwab
@ 2006-02-04 18:26 ` Paul Collins
  2006-02-04 22:56   ` Benjamin Herrenschmidt
  2 siblings, 1 reply; 9+ messages in thread
From: Paul Collins @ 2006-02-04 18:26 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, linuxppc64-dev

Hi Ben,

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> My patch reworking the PowerMac i2c code break the sound drivers as they
> used to rely on some broken behaviour of i2c-keywest that is gone now.
> This patch should fix them (tested on a g5 with alsa only). It might
> also fix an oops if the alsa driver hits an unsupported chip.

Applied Linus's current git tree, this patch makes ALSA sound on my
PowerBook5,4 work again.  The second patch does not work because the
i2c wrapper (I assume that's what i2c_smbus_write_i2c_block_data is)
has apparently not yet returned.

It would be nice to have this fix in 2.6.16 if possible.

> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>
> Index: linux-work/sound/ppc/tumbler.c
> ===================================================================
> --- linux-work.orig/sound/ppc/tumbler.c	2005-11-24 17:19:14.000000000 +1100
> +++ linux-work/sound/ppc/tumbler.c	2006-01-08 15:18:09.000000000 +1100
> @@ -137,6 +137,22 @@ static int send_init_client(pmac_keywest
>  	return 0;
>  }
>  
> +static int tumbler_write_block(struct i2c_client *client, u8 reg, int len,
> +			       u8 *values)
> +{
> +        union i2c_smbus_data data;
> +        int err;
> +
> +        data.block[0] = len;
> +	memcpy(&data.block[1], values, len);
> +        err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
> +                             I2C_SMBUS_WRITE, reg, I2C_SMBUS_I2C_BLOCK_DATA,
> +                             &data);
> +        return err;
> +}
> +
> +
> +
>  
>  static int tumbler_init_client(pmac_keywest_t *i2c)
>  {
> @@ -239,8 +255,7 @@ static int tumbler_set_master_volume(pma
>  	block[4] = (right_vol >> 8)  & 0xff;
>  	block[5] = (right_vol >> 0)  & 0xff;
>    
> -	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL,
> -				       6, block) < 0) {
> +	if (tumbler_write_block(mix->i2c.client, TAS_REG_VOL, 6, block) < 0) {
>  		snd_printk("failed to set volume \n");
>  		return -EINVAL;
>  	}
> @@ -340,8 +355,7 @@ static int tumbler_set_drc(pmac_tumbler_
>  		val[1] = 0;
>  	}
>  
> -	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
> -				       2, val) < 0) {
> +	if (tumbler_write_block(mix->i2c.client, TAS_REG_DRC, 2, val) < 0) {
>  		snd_printk("failed to set DRC\n");
>  		return -EINVAL;
>  	}
> @@ -376,8 +390,7 @@ static int snapper_set_drc(pmac_tumbler_
>  	val[4] = 0x60;
>  	val[5] = 0xa0;
>  
> -	if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC,
> -				       6, val) < 0) {
> +	if (tumbler_write_block(mix->i2c.client, TAS_REG_DRC, 6, val) < 0) {
>  		snd_printk("failed to set DRC\n");
>  		return -EINVAL;
>  	}
> @@ -481,8 +494,8 @@ static int tumbler_set_mono_volume(pmac_
>  	vol = info->table[vol];
>  	for (i = 0; i < info->bytes; i++)
>  		block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff;
> -	if (i2c_smbus_write_block_data(mix->i2c.client, info->reg,
> -				       info->bytes, block) < 0) {
> +	if (tumbler_write_block(mix->i2c.client, info->reg,
> +				  info->bytes, block) < 0) {
>  		snd_printk("failed to set mono volume %d\n", info->index);
>  		return -EINVAL;
>  	}
> @@ -611,7 +624,7 @@ static int snapper_set_mix_vol1(pmac_tum
>  		for (j = 0; j < 3; j++)
>  			block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff;
>  	}
> -	if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) {
> +	if (tumbler_write_block(mix->i2c.client, reg, 9, block) < 0) {
>  		snd_printk("failed to set mono volume %d\n", reg);
>  		return -EINVAL;
>  	}
> Index: linux-work/sound/oss/dmasound/tas_common.h
> ===================================================================
> --- linux-work.orig/sound/oss/dmasound/tas_common.h	2005-11-24 17:19:14.000000000 +1100
> +++ linux-work/sound/oss/dmasound/tas_common.h	2006-01-08 15:33:29.000000000 +1100
> @@ -157,6 +157,21 @@ tas_mono_to_stereo(uint mono)
>  	return mono | (mono<<8);
>  }
>  
> +static int tas_write_block(struct i2c_client *client, u8 reg, int len, u8 *vals)
> +{
> +        union i2c_smbus_data data;
> +        int err;
> +
> +        data.block[0] = len;
> +	memcpy(&data.block[1], vals, len);
> +        err = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
> +                             I2C_SMBUS_WRITE, reg, I2C_SMBUS_I2C_BLOCK_DATA,
> +                             &data);
> +        return err;
> +}
> +
> +
> +
>  /*
>   * Todo: make these functions a bit more efficient !
>   */
> @@ -178,10 +193,8 @@ tas_write_register(	struct tas_data_t *s
>  	if (write_mode & WRITE_SHADOW)
>  		memcpy(self->shadow[reg_num],data,reg_width);
>  	if (write_mode & WRITE_HW) {
> -		rc=i2c_smbus_write_block_data(self->client,
> -					      reg_num,
> -					      reg_width,
> -					      data);
> +		rc = tas_write_block(self->client, reg_num,
> +				     reg_width, data);
>  		if (rc < 0) {
>  			printk("tas: I2C block write failed \n");  
>  			return rc; 
> @@ -199,10 +212,8 @@ tas_sync_register(	struct tas_data_t *se
>  
>  	if (reg_width==0 || self==NULL)
>  		return -EINVAL;
> -	rc=i2c_smbus_write_block_data(self->client,
> -				      reg_num,
> -				      reg_width,
> -				      self->shadow[reg_num]);
> +	rc = tas_write_block(self->client, reg_num,
> +			     reg_width, self->shadow[reg_num]);
>  	if (rc < 0) {
>  		printk("tas: I2C block write failed \n");
>  		return rc;
> Index: linux-work/sound/ppc/pmac.c
> ===================================================================
> --- linux-work.orig/sound/ppc/pmac.c	2005-12-19 16:13:48.000000000 +1100
> +++ linux-work/sound/ppc/pmac.c	2006-01-08 15:37:10.000000000 +1100
> @@ -74,7 +74,7 @@ static int snd_pmac_dbdma_alloc(pmac_t *
>  
>  static void snd_pmac_dbdma_free(pmac_t *chip, pmac_dbdma_t *rec)
>  {
> -	if (rec) {
> +	if (rec->space) {
>  		unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
>  
>  		dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base);
> @@ -895,6 +895,7 @@ static int __init snd_pmac_detect(pmac_t
>  	chip->can_capture = 1;
>  	chip->num_freqs = ARRAY_SIZE(awacs_freqs);
>  	chip->freq_table = awacs_freqs;
> +	chip->pdev = NULL;
>  
>  	chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */
>  

-- 
Dag vijandelijk luchtschip de huismeester is dood

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] powerpc: Fix PowerMac sound i2c
  2006-02-04 18:26 ` Paul Collins
@ 2006-02-04 22:56   ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2006-02-04 22:56 UTC (permalink / raw)
  To: Paul Collins; +Cc: Andrew Morton, linuxppc-dev list, linuxppc64-dev

On Sat, 2006-02-04 at 18:26 +0000, Paul Collins wrote:
> Hi Ben,
> 
> Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:
> 
> > My patch reworking the PowerMac i2c code break the sound drivers as they
> > used to rely on some broken behaviour of i2c-keywest that is gone now.
> > This patch should fix them (tested on a g5 with alsa only). It might
> > also fix an oops if the alsa driver hits an unsupported chip.
> 
> Applied Linus's current git tree, this patch makes ALSA sound on my
> PowerBook5,4 work again.  The second patch does not work because the
> i2c wrapper (I assume that's what i2c_smbus_write_i2c_block_data is)
> has apparently not yet returned.
> 
> It would be nice to have this fix in 2.6.16 if possible.

The second patch is the one that should go in, but it relies on an i2c
fix (undoing some Bunk damage) that is still staging in Greg tree... I
don't know what's up with that, I'll ask around.

Ben.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-02-04 22:56 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-08  4:52 [PATCH] powerpc: Fix PowerMac sound i2c Benjamin Herrenschmidt
2006-01-08  4:55 ` Hollis Blanchard
2006-01-08  6:22   ` Benjamin Herrenschmidt
2006-01-08 23:37     ` Benjamin Herrenschmidt
2006-01-08 10:37 ` Andreas Schwab
2006-01-08 13:30   ` Andreas Schwab
2006-01-08 21:03   ` Benjamin Herrenschmidt
2006-02-04 18:26 ` Paul Collins
2006-02-04 22:56   ` Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).