From 5392a47c1ac2212447b735bf0570b8e4249582a6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 8 Dec 2008 12:01:07 -0800 Subject: [PATCH] REMOVE OMAP LEGACY CODE: Remove old tlv320aic23.c code All omap audio development must use ASoC driver as suggested by David Brownell. Please see sound/soc/omap. For patches, please send them against the mainline tree to the alsa list with linux-omap list Cc'd. See also the previous patch 4a6f6c8336db39d134b42b0ba083e79ed7fd536b. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-nokia770.c | 8 +- arch/arm/plat-omap/include/mach/aic23.h | 126 ----- drivers/i2c/chips/Kconfig | 7 - drivers/i2c/chips/Makefile | 1 - drivers/i2c/chips/tlv320aic23.c | 675 ------------------------ 5 files changed, 7 insertions(+), 810 deletions(-) delete mode 100644 arch/arm/plat-omap/include/mach/aic23.h delete mode 100644 drivers/i2c/chips/tlv320aic23.c diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 7f50fade7f9..7fdb725d2ba 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -303,6 +302,13 @@ static DEFINE_MUTEX(audio_pwr_lock); */ static int audio_pwr_state = -1; +static inline void aic23_power_up(void) +{ +} +static inline void aic23_power_down(void) +{ +} + /* * audio_pwr_up / down should be called under audio_pwr_lock */ diff --git a/arch/arm/plat-omap/include/mach/aic23.h b/arch/arm/plat-omap/include/mach/aic23.h deleted file mode 100644 index 188fe8b1308..00000000000 --- a/arch/arm/plat-omap/include/mach/aic23.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * arch/arm/plat-omap/include/mach/aic23.h - * - * Hardware definitions for TI TLV320AIC23 audio codec - * - * Copyright (C) 2002 RidgeRun, Inc. - * Author: Steve Johnson - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __ASM_ARCH_AIC23_H -#define __ASM_ARCH_AIC23_H - -// Codec TLV320AIC23 -#define LEFT_LINE_VOLUME_ADDR 0x00 -#define RIGHT_LINE_VOLUME_ADDR 0x01 -#define LEFT_CHANNEL_VOLUME_ADDR 0x02 -#define RIGHT_CHANNEL_VOLUME_ADDR 0x03 -#define ANALOG_AUDIO_CONTROL_ADDR 0x04 -#define DIGITAL_AUDIO_CONTROL_ADDR 0x05 -#define POWER_DOWN_CONTROL_ADDR 0x06 -#define DIGITAL_AUDIO_FORMAT_ADDR 0x07 -#define SAMPLE_RATE_CONTROL_ADDR 0x08 -#define DIGITAL_INTERFACE_ACT_ADDR 0x09 -#define RESET_CONTROL_ADDR 0x0F - -// Left (right) line input volume control register -#define LRS_ENABLED 0x0100 -#define LIM_MUTED 0x0080 -#define LIV_DEFAULT 0x0017 -#define LIV_MAX 0x001f -#define LIV_MIN 0x0000 - -// Left (right) channel headphone volume control register -#define LZC_ON 0x0080 -#define LHV_DEFAULT 0x0079 -#define LHV_MAX 0x007f -#define LHV_MIN 0x0000 - -// Analog audio path control register -#define STA_REG(x) ((x)<<6) -#define STE_ENABLED 0x0020 -#define DAC_SELECTED 0x0010 -#define BYPASS_ON 0x0008 -#define INSEL_MIC 0x0004 -#define MICM_MUTED 0x0002 -#define MICB_20DB 0x0001 - -// Digital audio path control register -#define DACM_MUTE 0x0008 -#define DEEMP_32K 0x0002 -#define DEEMP_44K 0x0004 -#define DEEMP_48K 0x0006 -#define ADCHP_ON 0x0001 - -// Power control down register -#define DEVICE_POWER_OFF 0x0080 -#define CLK_OFF 0x0040 -#define OSC_OFF 0x0020 -#define OUT_OFF 0x0010 -#define DAC_OFF 0x0008 -#define ADC_OFF 0x0004 -#define MIC_OFF 0x0002 -#define LINE_OFF 0x0001 - -// Digital audio interface register -#define MS_MASTER 0x0040 -#define LRSWAP_ON 0x0020 -#define LRP_ON 0x0010 -#define IWL_16 0x0000 -#define IWL_20 0x0004 -#define IWL_24 0x0008 -#define IWL_32 0x000C -#define FOR_I2S 0x0002 -#define FOR_DSP 0x0003 - -// Sample rate control register -#define CLKOUT_HALF 0x0080 -#define CLKIN_HALF 0x0040 -#define BOSR_384fs 0x0002 // BOSR_272fs when in USB mode -#define USB_CLK_ON 0x0001 -#define SR_MASK 0xf -#define CLKOUT_SHIFT 7 -#define CLKIN_SHIFT 6 -#define SR_SHIFT 2 -#define BOSR_SHIFT 1 - -// Digital interface register -#define ACT_ON 0x0001 - -#define TLV320AIC23ID1 (0x1a) // cs low -#define TLV320AIC23ID2 (0x1b) // cs high - -#ifdef CONFIG_SENSORS_TLV320AIC23 -extern void aic23_power_up(void); -extern void aic23_power_down(void); -#else -static inline void aic23_power_up(void) -{ -} - -static inline void aic23_power_down(void) -{ -} -#endif - -#endif /* __ASM_ARCH_AIC23_H */ diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index d61589b2388..7404647adc2 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -139,13 +139,6 @@ config TPS65010 This driver can also be built as a module. If so, the module will be called tps65010. -config SENSORS_TLV320AIC23 - tristate "Texas Instruments TLV320AIC23 Codec" - depends on I2C && I2C_OMAP - help - If you say yes here you get support for the I2C control - interface for Texas Instruments TLV320AIC23 audio codec. - config TWL4030_MADC tristate "TWL4030 MADC Driver" depends on TWL4030_CORE diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index d82019c0ada..7076c30221a 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_PCF8575) += pcf8575.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o obj-$(CONFIG_TPS65010) += tps65010.o -obj-$(CONFIG_SENSORS_TLV320AIC23) += tlv320aic23.o obj-$(CONFIG_MENELAUS) += menelaus.o obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_MCU_MPC8349EMITX) += mcu_mpc8349emitx.o diff --git a/drivers/i2c/chips/tlv320aic23.c b/drivers/i2c/chips/tlv320aic23.c deleted file mode 100644 index 10671e803e4..00000000000 --- a/drivers/i2c/chips/tlv320aic23.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * Texas Instrumens TLV320AIC23 audio codec's i2c interface. - * - * Copyright (c) by Kai Svahn - * Copyright (c) by Jussi Laako - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TLV320AIC23_VERSION "1.8" -#define TLV320AIC23_DATE "10-Feb-2006" -#define MAX_VOL 100 -#define MIN_VOL 0 -#define MAX_GAIN 100 -#define MIN_GAIN 0 -#define OUTPUT_VOLUME_MIN LHV_MIN -#define OUTPUT_VOLUME_MAX LHV_MAX -#define OUTPUT_VOLUME_RANGE (OUTPUT_VOLUME_MAX - OUTPUT_VOLUME_MIN) -#define INPUT_VOLUME_MIN LIV_MIN -#define INPUT_VOLUME_MAX LIV_MAX -#define INPUT_VOLUME_RANGE (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN) - -/* I2C Addresses to scan */ -static unsigned short normal_i2c[] = { TLV320AIC23ID1, TLV320AIC23ID2, \ - I2C_CLIENT_END }; -/*static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };*/ - -/* This makes all addr_data:s */ -I2C_CLIENT_INSMOD; - -static struct i2c_driver aic23_driver; -static struct i2c_client *new_client; -static int selftest; -static struct platform_device audio_i2c_device; - -static struct aic23_info { - u16 volume_reg_left; - u16 volume_reg_right; - u16 input_gain_reg_left; - u16 input_gain_reg_right; - u16 power; /* For POWER_DOWN_CONTROL_ADDR */ - u16 mask; /* For ANALOG_AUDIO_CONTROL_ADDR */ - int mic_loopback; - int mic_enable; - int sta; - int power_down; - int initialized; -} aic23_info_l; - -static int _aic23_write_value(struct i2c_client *client, u8 reg, u16 value) -{ - u8 val, wreg; - - /* TLV320AIC23 has 7 bit address and 9 bits of data - * so we need to switch one data bit into reg and rest - * of data into val - */ - - wreg = (reg << 1); - val = (0x01 & (value >> 8)); - wreg = (wreg | val); - val = (0x00ff & value); - - return i2c_smbus_write_byte_data(client, wreg, val); -} - -int aic23_write_value(u8 reg, u16 value) -{ - static struct i2c_client *client; - client = new_client; - _aic23_write_value(client, reg, value); - - return 0; -} - -/* - * Configures the McBSP3 which is used to send clock to the AIC23 codec. - * The input clock rate from DSP is 12MHz. - * The DSP clock must be on before this is called. - */ -static int omap_mcbsp3_aic23_clock_init(void) -{ - u16 w; - - /* enable 12MHz clock to mcbsp 1 & 3 */ - __raw_writew(__raw_readw(DSP_IDLECT2) | (1<<1), DSP_IDLECT2); - __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1<<1, DSP_RSTCT2); - - /* disable sample rate generator */ - OMAP_MCBSP_WRITE(OMAP1610_MCBSP3_BASE, SPCR1, 0x0000); - OMAP_MCBSP_WRITE(OMAP1610_MCBSP3_BASE, SPCR2, 0x0000); - - /* pin control register */ - OMAP_MCBSP_WRITE(OMAP1610_MCBSP3_BASE, PCR0,(CLKXM | CLKXP | CLKRP)); - - /* configure srg to send 12MHz pulse from dsp peripheral clock */ - OMAP_MCBSP_WRITE(OMAP1610_MCBSP3_BASE, SRGR1, 0x0000); - OMAP_MCBSP_WRITE(OMAP1610_MCBSP3_BASE, SRGR2, CLKSM); - - /* enable sample rate generator */ - w = OMAP_MCBSP_READ(OMAP1610_MCBSP3_BASE, SPCR2); - OMAP_MCBSP_WRITE(OMAP1610_MCBSP3_BASE, SPCR2, (w | FREE | GRST)); - printk("Clock enabled to MCBSP1 & 3 \n"); - - return 0; -} - -static int aic23_detect_client(struct i2c_adapter *adapter, int address, - int kind) -{ - int err = 0; - const char *client_name = "TLV320AIC23 Audio Codec"; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_WRITE_BYTE)) { - printk(KERN_WARNING "%s functionality check failed\n", - client_name); - return err; - } - - if (!(new_client = kmalloc(sizeof(struct i2c_client), - GFP_KERNEL))) { - err = -ENOMEM; - printk(KERN_WARNING "Couldn't allocate memory for %s\n", - client_name); - return err; - } - - memset(new_client, 0x00, sizeof(struct i2c_client)); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &aic23_driver; - new_client->flags = 0; - strlcpy(new_client->name, client_name, I2C_NAME_SIZE); - - if ((err = i2c_attach_client(new_client))) { - printk(KERN_WARNING "Couldn't attach %s\n", client_name); - kfree(new_client); - return err; - } - - if (platform_device_register(&audio_i2c_device)) { - printk(KERN_WARNING "Failed to register audio i2c device\n"); - selftest = -ENODEV; - return selftest; - } - /* FIXME: Do in board-specific file */ - omap_mcbsp3_aic23_clock_init(); - - if (!aic23_info_l.power_down) - aic23_power_up(); - aic23_info_l.initialized = 1; - - return 0; -} - -static int aic23_detach_client(struct i2c_client *client) -{ - int err; - - platform_device_unregister(&audio_i2c_device); - - if ((err = i2c_detach_client(client))) { - printk("aic23.o: Client deregistration failed, \ - client not detached.\n"); - return err; - } - kfree(client); - return 0; -} - -static int aic23_attach_adapter(struct i2c_adapter *adapter) -{ - int res; - - res = i2c_probe(adapter, &addr_data, &aic23_detect_client); - return res; -} - -static struct i2c_driver aic23_driver = { - .driver = { - .name = "OMAP+TLV320AIC23 codec", - /*.flags = I2C_DF_NOTIFY,*/ - }, - .id = I2C_DRIVERID_MISC, /* Experimental ID */ - .attach_adapter = aic23_attach_adapter, - .detach_client = aic23_detach_client, -}; - -static void update_volume_left(int volume) -{ - u16 val = 0; - val = ((volume * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MIN; - aic23_write_value(LEFT_CHANNEL_VOLUME_ADDR, val); - aic23_info_l.volume_reg_left = volume; -} - -static void update_volume_right(int volume) -{ - u16 val = 0; - val = ((volume * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MIN; - aic23_write_value(RIGHT_CHANNEL_VOLUME_ADDR, val); - aic23_info_l.volume_reg_right = volume; -} - -static void set_mic(int mic_en) -{ - u16 dg_ctrl; - - if (mic_en) { - aic23_info_l.power = OSC_OFF | LINE_OFF; - dg_ctrl = ADCHP_ON; - aic23_info_l.mask &= ~MICM_MUTED; - aic23_info_l.mask |= MICB_20DB; /* STE_ENABLED */ - } else { - aic23_info_l.power = - OSC_OFF | ADC_OFF | MIC_OFF | LINE_OFF; - dg_ctrl = 0x00; - aic23_info_l.mask = - DAC_SELECTED | INSEL_MIC | MICM_MUTED; - } - aic23_write_value(POWER_DOWN_CONTROL_ADDR, - aic23_info_l.power); - aic23_write_value(DIGITAL_AUDIO_CONTROL_ADDR, dg_ctrl); - aic23_write_value(ANALOG_AUDIO_CONTROL_ADDR, - aic23_info_l.mask); - aic23_info_l.mic_enable = mic_en; - - printk(KERN_INFO "aic23 mic state: %i\n", mic_en); -} - -static void aic23_init_power(void) -{ - aic23_write_value(RESET_CONTROL_ADDR, 0x00); - - if (aic23_info_l.initialized == 0) { - aic23_write_value(LEFT_CHANNEL_VOLUME_ADDR, LHV_MIN); - aic23_write_value(RIGHT_CHANNEL_VOLUME_ADDR, LHV_MIN); - } - else { - update_volume_left(aic23_info_l.volume_reg_left); - update_volume_right(aic23_info_l.volume_reg_right); - } - - aic23_info_l.mask = DAC_SELECTED | INSEL_MIC | MICM_MUTED; - aic23_write_value(ANALOG_AUDIO_CONTROL_ADDR, - aic23_info_l.mask); - aic23_write_value(DIGITAL_AUDIO_CONTROL_ADDR, 0x00); - aic23_write_value(DIGITAL_AUDIO_FORMAT_ADDR, LRP_ON | FOR_DSP); - aic23_write_value(SAMPLE_RATE_CONTROL_ADDR, USB_CLK_ON); - aic23_write_value(DIGITAL_INTERFACE_ACT_ADDR, ACT_ON); - aic23_info_l.power = OSC_OFF | ADC_OFF | MIC_OFF | LINE_OFF; - aic23_write_value(POWER_DOWN_CONTROL_ADDR, - aic23_info_l.power); - - /* enable mic input */ - if (aic23_info_l.mic_enable) - set_mic(aic23_info_l.mic_enable); - - printk(KERN_INFO "aic23_init_power() done\n"); -} - -void aic23_power_down(void) -{ - if (aic23_info_l.initialized) { - printk("aic23 powering down\n"); - aic23_write_value(POWER_DOWN_CONTROL_ADDR, 0xff); - } - aic23_info_l.power_down = 1; -} - -void aic23_power_up(void) -{ - if (aic23_info_l.initialized) { - printk("aic23 powering up\n"); - aic23_init_power(); - } - aic23_info_l.power_down = 0; -} - -/*----------------------------------------------------------------------*/ -/* sysfs initializations */ -/*----------------------------------------------------------------------*/ - -static ssize_t store_volume_left(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - signed volume; - - sscanf(buf, "%i", &volume); - - if (volume < MIN_VOL) { - aic23_power_down(); - return count; - } else if (volume > MIN_VOL && aic23_info_l.power_down) { - aic23_info_l.volume_reg_left = volume; - aic23_power_up(); - return count; - } - if (volume > MAX_VOL) - volume = MAX_VOL; - - update_volume_left(volume); - return count; -} - -static ssize_t show_volume_left(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", aic23_info_l.volume_reg_left); -} - -static DEVICE_ATTR(volume_left, S_IRUGO | S_IWUGO, - show_volume_left, store_volume_left); - -static ssize_t store_volume_right(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - signed volume; - - sscanf(buf, "%i", &volume); - if (volume < MIN_VOL) { - aic23_power_down(); - return count; - } else if (volume > MIN_VOL && aic23_info_l.power_down) { - aic23_info_l.volume_reg_right = volume; - aic23_power_up(); - return count; - } - if (volume > MAX_VOL) - volume = MAX_VOL; - - update_volume_right(volume); - return count; -} - -static ssize_t show_volume_right(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", aic23_info_l.volume_reg_right); -} - -static DEVICE_ATTR(volume_right, S_IRUGO | S_IWUGO, - show_volume_right, store_volume_right); - -static ssize_t store_gain_left(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - u16 val = 0; - unsigned gain; - - sscanf(buf, "%u", &gain); - if (gain > MAX_VOL) - gain = MAX_VOL; - - val = ((gain * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN; - aic23_write_value(LEFT_LINE_VOLUME_ADDR, val); - aic23_info_l.input_gain_reg_left = gain; - - return count; -} - -static ssize_t show_gain_left(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", aic23_info_l.input_gain_reg_left); -} - -static DEVICE_ATTR(gain_left, S_IRUGO | S_IWUSR, show_gain_left, - store_gain_left); - -static ssize_t store_gain_right(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - u16 val = 0; - unsigned gain; - - sscanf(buf, "%u", &gain); - if (gain > MAX_VOL) - gain = MAX_VOL; - - val = ((gain * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN; - aic23_write_value(RIGHT_LINE_VOLUME_ADDR, val); - aic23_info_l.input_gain_reg_right = gain; - - return count; -} - -static ssize_t show_gain_right(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%u\n", aic23_info_l.input_gain_reg_right); -} - -static DEVICE_ATTR(gain_right, S_IRUGO | S_IWUSR, show_gain_right, - store_gain_right); - -static ssize_t store_mic_loopback(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int mic; - - sscanf(buf, "%i", &mic); - if (mic > 0) { - aic23_write_value(POWER_DOWN_CONTROL_ADDR, \ - OSC_OFF | ADC_OFF | LINE_OFF); - aic23_info_l.mask = STE_ENABLED | DAC_SELECTED \ - | INSEL_MIC | MICB_20DB; - aic23_write_value(ANALOG_AUDIO_CONTROL_ADDR, - aic23_info_l.mask); - mic = 1; - } - else { - aic23_write_value(POWER_DOWN_CONTROL_ADDR, \ - OSC_OFF | ADC_OFF | MIC_OFF | LINE_OFF); - mic = 0; - } - aic23_info_l.mic_loopback = mic; - - return count; -} - -static ssize_t show_mic_loopback(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%i\n", aic23_info_l.mic_loopback); -} - -static DEVICE_ATTR(mic_loopback, S_IRUGO | S_IWUSR, - show_mic_loopback, store_mic_loopback); - -static ssize_t store_st_attenuation(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned sta; - u16 tmp; - - sscanf(buf, "%u", &sta); - if (sta > 3) - sta = 3; - - tmp = aic23_info_l.mask; - tmp &= 0x3f; - - aic23_info_l.mask = tmp | STA_REG(sta); - aic23_write_value(ANALOG_AUDIO_CONTROL_ADDR, - aic23_info_l.mask); - aic23_info_l.sta = sta; - - return count; -} - -static ssize_t show_st_attenuation(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%i\n", aic23_info_l.sta); -} - -static DEVICE_ATTR(st_attenuation, S_IRUGO | S_IWUSR, - show_st_attenuation, store_st_attenuation); - -static ssize_t store_mic_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int mic; - - sscanf(buf, "%i", &mic); - set_mic(mic); - - return count; -} - -static ssize_t show_mic_enable(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%i\n", aic23_info_l.mic_enable); -} - -static DEVICE_ATTR(mic_enable, S_IRUGO | S_IWUSR, - show_mic_enable, store_mic_enable); - -static ssize_t show_audio_selftest(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%i\n", selftest); -} - -static DEVICE_ATTR(audio_selftest, S_IRUGO | S_IWUSR, - show_audio_selftest, NULL); - -static int audio_i2c_probe(struct platform_device *dev) -{ - int r; - - if ((r = device_create_file(&dev->dev, &dev_attr_volume_left)) != 0) - return r; - else if ((r = device_create_file(&dev->dev, - &dev_attr_volume_right)) != 0) - goto err_volume_left; - else if ((r = device_create_file(&dev->dev, - &dev_attr_gain_right)) != 0) - goto err_volume_right; - else if ((r = device_create_file(&dev->dev, - &dev_attr_gain_left)) != 0) - goto err_gain_right; - else if ((r = device_create_file(&dev->dev, - &dev_attr_mic_loopback)) != 0) - goto err_gain_left; - else if ((r = device_create_file(&dev->dev, - &dev_attr_mic_enable)) != 0) - goto err_mic_loopback; - else if ((r = device_create_file(&dev->dev, - &dev_attr_st_attenuation)) != 0) - goto err_mic_enable; - else if ((r = device_create_file(&dev->dev, - &dev_attr_audio_selftest)) != 0) - goto err_st_attenuation; - else - return r; - -err_st_attenuation: - device_remove_file(&dev->dev, &dev_attr_st_attenuation); -err_mic_enable: - device_remove_file(&dev->dev, &dev_attr_mic_enable); -err_mic_loopback: - device_remove_file(&dev->dev, &dev_attr_mic_loopback); -err_gain_left: - device_remove_file(&dev->dev, &dev_attr_gain_left); -err_gain_right: - device_remove_file(&dev->dev, &dev_attr_gain_right); -err_volume_right: - device_remove_file(&dev->dev, &dev_attr_volume_right); -err_volume_left: - device_remove_file(&dev->dev, &dev_attr_volume_left); - - return r; -} - -static int audio_i2c_remove(struct platform_device *dev) -{ - device_remove_file(&dev->dev, &dev_attr_st_attenuation); - device_remove_file(&dev->dev, &dev_attr_mic_enable); - device_remove_file(&dev->dev, &dev_attr_mic_loopback); - device_remove_file(&dev->dev, &dev_attr_gain_left); - device_remove_file(&dev->dev, &dev_attr_gain_right); - device_remove_file(&dev->dev, &dev_attr_volume_right); - device_remove_file(&dev->dev, &dev_attr_volume_left); - - return 0; -} - -/*----------------------------------------------------------------*/ -/* PM functions */ -/*----------------------------------------------------------------*/ - -static void audio_i2c_shutdown(struct platform_device *dev) -{ - /* Let's mute the codec before powering off to prevent - * glitch in the sound - */ - aic23_write_value(LEFT_CHANNEL_VOLUME_ADDR, LHV_MIN); - aic23_write_value(RIGHT_CHANNEL_VOLUME_ADDR, LHV_MIN); - aic23_power_down(); -} - -static int audio_i2c_suspend(struct platform_device *dev, pm_message_t state) -{ - /* Let's mute the codec before powering off to prevent - * glitch in the sound - */ - aic23_write_value(LEFT_CHANNEL_VOLUME_ADDR, LHV_MIN); - aic23_write_value(RIGHT_CHANNEL_VOLUME_ADDR, LHV_MIN); - aic23_power_down(); - - return 0; -} - -static int audio_i2c_resume(struct platform_device *dev) -{ - aic23_power_up(); - - return 0; -} - -static struct platform_driver audio_i2c_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "audio-i2c", - }, - .shutdown = audio_i2c_shutdown, - .probe = audio_i2c_probe, - .remove = audio_i2c_remove, - .suspend = audio_i2c_suspend, - .resume = audio_i2c_resume, -}; - -static struct platform_device audio_i2c_device = { - .name = "audio-i2c", - .id = -1, -}; - -/*----------------------------------------------------------------*/ - -static int __init aic23_init(void) -{ - selftest = 0; - aic23_info_l.initialized = 0; - - if (i2c_add_driver(&aic23_driver)) { - printk("aic23 i2c: Driver registration failed, \ - module not inserted.\n"); - selftest = -ENODEV; - return selftest; - } - - if (platform_driver_register(&audio_i2c_driver)) { - printk(KERN_WARNING "Failed to register audio i2c driver\n"); - selftest = -ENODEV; - return selftest; - } - - printk("TLV320AIC23 I2C version %s (%s)\n", - TLV320AIC23_VERSION, TLV320AIC23_DATE); - - return selftest; -} - -static void __exit aic23_exit(void) -{ - aic23_power_down(); - i2c_del_driver(&aic23_driver); - - platform_driver_unregister(&audio_i2c_driver); -} - -MODULE_AUTHOR("Kai Svahn "); -MODULE_DESCRIPTION("I2C interface for TLV320AIC23 codec."); -MODULE_LICENSE("GPL"); - -module_init(aic23_init) -module_exit(aic23_exit) - -EXPORT_SYMBOL(aic23_write_value); -EXPORT_SYMBOL(aic23_power_up); -EXPORT_SYMBOL(aic23_power_down); -- 2.41.3