Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757719Ab1BKQFs (ORCPT ); Fri, 11 Feb 2011 11:05:48 -0500 Received: from mail-iy0-f174.google.com ([209.85.210.174]:49457 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757707Ab1BKQFr convert rfc822-to-8bit (ORCPT ); Fri, 11 Feb 2011 11:05:47 -0500 MIME-Version: 1.0 In-Reply-To: <1297439772-16209-1-git-send-email-biessmann@corscience.de> References: <1297439772-16209-1-git-send-email-biessmann@corscience.de> From: Grant Likely Date: Fri, 11 Feb 2011 09:05:19 -0700 X-Google-Sender-Auth: 4w3fjehpnoxlIxcFfa8W4SFkspE Message-ID: Subject: Re: [PATCH] at73c213: add support for at73c240 devices To: =?ISO-8859-1?Q?Andreas_Bie=DFmann?= Cc: kernel@avr32linux.org, "open list:SOUND" , Takashi Iwai , open list , "open list:SPI SUBSYSTEM" , Hans-Christian Egtvedt Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8BIT Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 11177 Lines: 280 On Fri, Feb 11, 2011 at 8:56 AM, Andreas Bie?mann wrote: > at73c240 is a successor of mature at73c213 and nearly register compatible. > > See http://www.atmel.com/dyn/resources/prod_documents/doc6484.pdf for > comparison of these two devices. > > Signed-off-by: Andreas Bie?mann Looks okay to me. Briefly-glanced-at-by: Grant Likely > --- > ?include/linux/spi/at73c213.h | ? ?1 + > ?sound/spi/at73c213.c ? ? ? ? | ?122 +++++++++++++++++++++++++++++++++--------- > ?sound/spi/at73c213.h ? ? ? ? | ? ?3 + > ?3 files changed, 101 insertions(+), 25 deletions(-) > > diff --git a/include/linux/spi/at73c213.h b/include/linux/spi/at73c213.h > index 0f20a70e..26d1f38 100644 > --- a/include/linux/spi/at73c213.h > +++ b/include/linux/spi/at73c213.h > @@ -19,6 +19,7 @@ > ?struct at73c213_board_info { > ? ? ? ?int ? ? ? ? ? ? ssc_id; > ? ? ? ?struct clk ? ? ?*dac_clk; > + ? ? ? bool ? ? ? ? ? ?is_at73c240; > ? ? ? ?char ? ? ? ? ? ?shortname[32]; > ?}; > > diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c > index 503ffb0..711aae4 100644 > --- a/sound/spi/at73c213.c > +++ b/sound/spi/at73c213.c > @@ -709,10 +709,44 @@ AT73C213_MONO_SWITCH("Aux Capture Switch", 0, DAC_CTRL, DAC_CTRL_ONAUXIN, > ?AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0), > ?}; > > +static struct snd_kcontrol_new snd_at73c240_controls[] __devinitdata = { > +AT73C213_STEREO("Master Playback Volume", 0, DAC_LMPG, DAC_RMPG, 0, 0, 0x1f, 1), > +AT73C213_STEREO("Master Playback Switch", 0, DAC_LMPG, DAC_RMPG, 5, 5, 1, 1), > +AT73C213_STEREO("PCM Playback Volume", 0, DAC_LLOG, DAC_RLOG, 0, 0, 0x1f, 1), > +AT73C213_STEREO("PCM Playback Switch", 0, DAC_LLOG, DAC_RLOG, 5, 5, 1, 1), > +AT73C213_MONO_SWITCH("Mono PA Playback Switch", 0, DAC_CTRL, > + ? ? ? ? ? ? ? ? ? ?(DAC_CTRL_ONPADRV-1), 0x01, 0), > +{ > + ? ? ? .iface ?= SNDRV_CTL_ELEM_IFACE_MIXER, > + ? ? ? .name ? = "PA Playback Volume", > + ? ? ? .index ?= 0, > + ? ? ? .info ? = snd_at73c213_pa_volume_info, > + ? ? ? .get ? ?= snd_at73c213_mono_get, > + ? ? ? .put ? ?= snd_at73c213_mono_put, > + ? ? ? .private_value ?= PA_CTRL | (PA_CTRL_APAGAIN << 8) | \ > + ? ? ? ? ? ? ? (0x0f << 16) | (1 << 24), > +}, > +AT73C213_MONO_SWITCH("PA Playback Switch", 0, PA_CTRL, (PA_CTRL_APAON-1), > + ? ? ? ? ? ? ? ? ? ?0x01, 0), > +{ > + ? ? ? .iface ?= SNDRV_CTL_ELEM_IFACE_MIXER, > + ? ? ? .name ? = "Line Capture Volume", > + ? ? ? .index ?= 0, > + ? ? ? .info ? = snd_at73c213_line_capture_volume_info, > + ? ? ? .get ? ?= snd_at73c213_stereo_get, > + ? ? ? .put ? ?= snd_at73c213_stereo_put, > + ? ? ? .private_value ?= DAC_LLIG | (DAC_RLIG << 8) | (0 << 16) | (0 << 19) > + ? ? ? ? ? ? ? | (0x1f << 24) | (1 << 22), > +}, > +AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0), > +}; > + > ?static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip) > ?{ > ? ? ? ?struct snd_card *card; > ? ? ? ?int errval, idx; > + ? ? ? struct snd_kcontrol_new *controls; > + ? ? ? int controls_size = 0; > > ? ? ? ?if (chip == NULL || chip->pcm == NULL) > ? ? ? ? ? ? ? ?return -EINVAL; > @@ -721,9 +755,17 @@ static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip) > > ? ? ? ?strcpy(card->mixername, chip->pcm->name); > > - ? ? ? for (idx = 0; idx < ARRAY_SIZE(snd_at73c213_controls); idx++) { > + ? ? ? if (chip->board->is_at73c240) { > + ? ? ? ? ? ? ? controls_size = ARRAY_SIZE(snd_at73c240_controls); > + ? ? ? ? ? ? ? controls = snd_at73c240_controls; > + ? ? ? } else { > + ? ? ? ? ? ? ? controls_size = ARRAY_SIZE(snd_at73c213_controls); > + ? ? ? ? ? ? ? controls = snd_at73c213_controls; > + ? ? ? } > + > + ? ? ? for (idx = 0; idx < controls_size; idx++) { > ? ? ? ? ? ? ? ?errval = snd_ctl_add(card, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? snd_ctl_new1(&snd_at73c213_controls[idx], > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? snd_ctl_new1(&controls[idx], > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?chip)); > ? ? ? ? ? ? ? ?if (errval < 0) > ? ? ? ? ? ? ? ? ? ? ? ?goto cleanup; > @@ -732,7 +774,7 @@ static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip) > ? ? ? ?return 0; > > ?cleanup: > - ? ? ? for (idx = 1; idx < ARRAY_SIZE(snd_at73c213_controls) + 1; idx++) { > + ? ? ? for (idx = 1; idx < controls_size + 1; idx++) { > ? ? ? ? ? ? ? ?struct snd_kcontrol *kctl; > ? ? ? ? ? ? ? ?kctl = snd_ctl_find_numid(card, idx); > ? ? ? ? ? ? ? ?if (kctl) > @@ -777,7 +819,7 @@ static int __devinit snd_at73c213_ssc_init(struct snd_at73c213 *chip) > ?static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip) > ?{ > ? ? ? ?int retval; > - ? ? ? unsigned char dac_ctrl = 0; > + ? ? ? unsigned char tmp_reg; > > ? ? ? ?retval = snd_at73c213_set_bitrate(chip); > ? ? ? ?if (retval) > @@ -799,7 +841,11 @@ static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip) > ? ? ? ?retval = snd_at73c213_write_reg(chip, DAC_PRECH, 0xff); > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out_clk; > - ? ? ? retval = snd_at73c213_write_reg(chip, PA_CTRL, (1< + ? ? ? if (chip->board->is_at73c240) > + ? ? ? ? ? ? ? tmp_reg = (1<<(PA_CTRL_APAPRECH-1)); > + ? ? ? else > + ? ? ? ? ? ? ? tmp_reg = (1< + ? ? ? retval = snd_at73c213_write_reg(chip, PA_CTRL, tmp_reg); > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out_clk; > ? ? ? ?retval = snd_at73c213_write_reg(chip, DAC_CTRL, > @@ -809,11 +855,13 @@ static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip) > > ? ? ? ?msleep(50); > > - ? ? ? /* Stop precharging PA. */ > - ? ? ? retval = snd_at73c213_write_reg(chip, PA_CTRL, > - ? ? ? ? ? ? ? ? ? ? ? (1< - ? ? ? if (retval) > - ? ? ? ? ? ? ? goto out_clk; > + ? ? ? if (!chip->board->is_at73c240) { > + ? ? ? ? ? ? ? /* Stop precharging PA. */ > + ? ? ? ? ? ? ? retval = snd_at73c213_write_reg(chip, PA_CTRL, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1< + ? ? ? ? ? ? ? if (retval) > + ? ? ? ? ? ? ? ? ? ? ? goto out_clk; > + ? ? ? } > > ? ? ? ?msleep(450); > > @@ -825,12 +873,18 @@ static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip) > ? ? ? ?msleep(1); > > ? ? ? ?/* Turn on DAC. */ > - ? ? ? dac_ctrl = (1< - ? ? ? ? ? ? ? | (1< - ? ? ? ? ? ? ? /* enable MONO PA */ > - ? ? ? ? ? ? ? | (1< + ? ? ? if (chip->board->is_at73c240) > + ? ? ? ? ? ? ? tmp_reg = (1< + ? ? ? ? ? ? ? ? ? ? ? | (1< + ? ? ? ? ? ? ? ? ? ? ? /* enable MONO PA */ > + ? ? ? ? ? ? ? ? ? ? ? | (1<<(DAC_CTRL_ONPADRV-1)); > + ? ? ? else > + ? ? ? ? ? ? ? tmp_reg = (1< + ? ? ? ? ? ? ? ? ? ? ? | (1< + ? ? ? ? ? ? ? ? ? ? ? /* enable MONO PA */ > + ? ? ? ? ? ? ? ? ? ? ? | (1< > - ? ? ? retval = snd_at73c213_write_reg(chip, DAC_CTRL, dac_ctrl); > + ? ? ? retval = snd_at73c213_write_reg(chip, DAC_CTRL, tmp_reg); > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out_clk; > > @@ -859,9 +913,19 @@ static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip) > ? ? ? ?retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11); > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out_clk; > - ? ? ? retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11); > - ? ? ? if (retval) > - ? ? ? ? ? ? ? goto out_clk; > + ? ? ? if (!chip->board->is_at73c240) { > + ? ? ? ? ? ? ? retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11); > + ? ? ? ? ? ? ? if (retval) > + ? ? ? ? ? ? ? ? ? ? ? goto out_clk; > + ? ? ? } > + > + ? ? ? /* enable I2S clock */ > + ? ? ? if (chip->board->is_at73c240) { > + ? ? ? ? ? ? ? retval = snd_at73c213_write_reg(chip, DAC_IS_CTRL, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1< + ? ? ? ? ? ? ? if (retval) > + ? ? ? ? ? ? ? ? ? ? ? goto out_clk; > + ? ? ? } > > ? ? ? ?/* Enable I2S device, i.e. clock output. */ > ? ? ? ?ssc_writel(chip->ssc->regs, CR, SSC_BIT(CR_TXEN)); > @@ -915,6 +979,10 @@ static int __devinit snd_at73c213_dev_init(struct snd_card *card, > ? ? ? ?memcpy(&chip->reg_image, &snd_at73c213_original_image, > ? ? ? ? ? ? ? ? ? ? ? ?sizeof(snd_at73c213_original_image)); > > + ? ? ? /* at73c240 has another reset value here */ > + ? ? ? if (chip->board->is_at73c240) > + ? ? ? ? ? ? ? chip->reg_image[PA_CTRL] = 0x0f; > + > ? ? ? ?retval = snd_at73c213_ssc_init(chip); > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out_irq; > @@ -1043,9 +1111,11 @@ static int __devexit snd_at73c213_remove(struct spi_device *spi) > ? ? ? ?retval = snd_at73c213_write_reg(chip, DAC_RLIG, 0x11); > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out; > - ? ? ? retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11); > - ? ? ? if (retval) > - ? ? ? ? ? ? ? goto out; > + ? ? ? if (!chip->board->is_at73c240) { > + ? ? ? ? ? ? ? retval = snd_at73c213_write_reg(chip, DAC_AUXG, 0x11); > + ? ? ? ? ? ? ? if (retval) > + ? ? ? ? ? ? ? ? ? ? ? goto out; > + ? ? ? } > > ? ? ? ?/* Turn off PA. */ > ? ? ? ?retval = snd_at73c213_write_reg(chip, PA_CTRL, > @@ -1053,10 +1123,12 @@ static int __devexit snd_at73c213_remove(struct spi_device *spi) > ? ? ? ?if (retval) > ? ? ? ? ? ? ? ?goto out; > ? ? ? ?msleep(10); > - ? ? ? retval = snd_at73c213_write_reg(chip, PA_CTRL, > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1 << PA_CTRL_APALP) | 0x0f); > - ? ? ? if (retval) > - ? ? ? ? ? ? ? goto out; > + ? ? ? if (!chip->board->is_at73c240) { > + ? ? ? ? ? ? ? retval = snd_at73c213_write_reg(chip, PA_CTRL, > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1 << PA_CTRL_APALP) | 0x0f); > + ? ? ? ? ? ? ? if (retval) > + ? ? ? ? ? ? ? ? ? ? ? goto out; > + ? ? ? } > > ? ? ? ?/* Turn off external DAC. */ > ? ? ? ?retval = snd_at73c213_write_reg(chip, DAC_CTRL, 0x0c); > diff --git a/sound/spi/at73c213.h b/sound/spi/at73c213.h > index fd8b372..3712d6e 100644 > --- a/sound/spi/at73c213.h > +++ b/sound/spi/at73c213.h > @@ -88,6 +88,9 @@ > ?#define DAC_MISC_DEEMPEN ? ? ? 2 > ?#define DAC_MISC_NBITS ? ? ? ? 0 > > +#define DAC_IS_CTRL ? ? ? ? ? ?0x0B > +#define DAC_IS_CTRL_IS_CTRL ? ?2 > + > ?/* DAC Precharge Control Register */ > ?#define DAC_PRECH ? ? ? ? ? ? ?0x0C > ?#define DAC_PRECH_PRCHGPDRV ? ?7 > -- > 1.7.2.3 > > > ------------------------------------------------------------------------------ > The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE: > Pinpoint memory and threading errors before they happen. > Find and fix more than 250 security defects in the development cycle. > Locate bottlenecks in serial and parallel code that limit performance. > http://p.sf.net/sfu/intel-dev2devfeb > _______________________________________________ > spi-devel-general mailing list > spi-devel-general@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/spi-devel-general > -- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/