linux/drivers/media/i2c/tvaudio.c

/*
 * Driver for simple i2c audio chips.
 *
 * Copyright (c) 2000 Gerd Knorr
 * based on code by:
 *   Eric Sandeen ([email protected])
 *   Steve VanDeBogart ([email protected])
 *   Greg Alexander ([email protected])
 *
 * For the TDA9875 part:
 * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source
 * and Eric Sandeen
 *
 * Copyright(c) 2005-2008 Mauro Carvalho Chehab
 *	- Some cleanups, code fixes, etc
 *	- Convert it to V4L2 API
 *
 * This code is placed under the terms of the GNU General Public License
 *
 * OPTIONS:
 *   debug - set to 1 if you'd like to see debug messages
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kthread.h>
#include <linux/freezer.h>

#include <media/i2c/tvaudio.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>

/* ---------------------------------------------------------------------- */
/* insmod args                                                            */

static int debug;	/* insmod parameter */
module_param(debug, int, 0644);

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();

#define UNSET

/* ---------------------------------------------------------------------- */
/* our structs                                                            */

#define MAXREGS

struct CHIPSTATE;
getvalue;
checkit;
initialize;
getrxsubchans;
setaudmode;

/* i2c command */
audiocmd;

/* chip description */
struct CHIPDESC {};

/* current state of the chip */
struct CHIPSTATE {};

static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
{}

static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
{}


/* ---------------------------------------------------------------------- */
/* i2c I/O functions                                                      */

static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
{}

static int chip_write_masked(struct CHIPSTATE *chip,
			     int subaddr, int val, int mask)
{}

static int chip_read(struct CHIPSTATE *chip)
{}

static int chip_read2(struct CHIPSTATE *chip, int subaddr)
{}

static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
{}

/* ---------------------------------------------------------------------- */
/* kernel thread for doing i2c stuff asyncronly
 *   right now it is used only to check the audio mode (mono/stereo/whatever)
 *   some time after switching to another TV channel, then turn on stereo
 *   if available, ...
 */

static void chip_thread_wake(struct timer_list *t)
{}

static int chip_thread(void *data)
{}

/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tda9840                */

#define TDA9840_SW
#define TDA9840_LVADJ
#define TDA9840_STADJ
#define TDA9840_TEST

#define TDA9840_MONO
#define TDA9840_STEREO
#define TDA9840_DUALA
#define TDA9840_DUALB
#define TDA9840_DUALAB
#define TDA9840_DUALBA
#define TDA9840_EXTERNAL

#define TDA9840_DS_DUAL
#define TDA9840_ST_STEREO
#define TDA9840_PONRES

#define TDA9840_TEST_INT1SN
#define TDA9840_TEST_INTFU

static int tda9840_getrxsubchans(struct CHIPSTATE *chip)
{}

static void tda9840_setaudmode(struct CHIPSTATE *chip, int mode)
{}

static int tda9840_checkit(struct CHIPSTATE *chip)
{}

/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tda985x                */

/* subaddresses for TDA9855 */
#define TDA9855_VR
#define TDA9855_VL
#define TDA9855_BA
#define TDA9855_TR
#define TDA9855_SW

/* subaddresses for TDA9850 */
#define TDA9850_C4

/* subaddesses for both chips */
#define TDA985x_C5
#define TDA985x_C6
#define TDA985x_C7
#define TDA985x_A1
#define TDA985x_A2
#define TDA985x_A3

/* Masks for bits in TDA9855 subaddresses */
/* 0x00 - VR in TDA9855 */
/* 0x01 - VL in TDA9855 */
/* lower 7 bits control gain from -71dB (0x28) to 16dB (0x7f)
 * in 1dB steps - mute is 0x27 */


/* 0x02 - BA in TDA9855 */
/* lower 5 bits control bass gain from -12dB (0x06) to 16.5dB (0x19)
 * in .5dB steps - 0 is 0x0E */


/* 0x03 - TR in TDA9855 */
/* 4 bits << 1 control treble gain from -12dB (0x3) to 12dB (0xb)
 * in 3dB steps - 0 is 0x7 */

/* Masks for bits in both chips' subaddresses */
/* 0x04 - SW in TDA9855, C4/Control 1 in TDA9850 */
/* Unique to TDA9855: */
/* 4 bits << 2 control subwoofer/surround gain from -14db (0x1) to 14db (0xf)
 * in 3dB steps - mute is 0x0 */

/* Unique to TDA9850: */
/* lower 4 bits control stereo noise threshold, over which stereo turns off
 * set to values of 0x00 through 0x0f for Ster1 through Ster16 */


/* 0x05 - C5 - Control 1 in TDA9855 , Control 2 in TDA9850*/
/* Unique to TDA9855: */
#define TDA9855_MUTE
#define TDA9855_AVL
#define TDA9855_LOUD
#define TDA9855_SUR
			     /* Bits 0 to 3 select various combinations
			      * of line in and line out, only the
			      * interesting ones are defined */
#define TDA9855_EXT
#define TDA9855_INT

/* Unique to TDA9850:  */
/* lower 4 bits control SAP noise threshold, over which SAP turns off
 * set to values of 0x00 through 0x0f for SAP1 through SAP16 */


/* 0x06 - C6 - Control 2 in TDA9855, Control 3 in TDA9850 */
/* Common to TDA9855 and TDA9850: */
#define TDA985x_SAP
#define TDA985x_MONOSAP
#define TDA985x_STEREO
#define TDA985x_MONO
#define TDA985x_LMU

/* Unique to TDA9855: */
#define TDA9855_TZCM
#define TDA9855_VZCM
#define TDA9855_LINEAR
#define TDA9855_PSEUDO
#define TDA9855_SPAT_30
#define TDA9855_SPAT_50
#define TDA9855_E_MONO

/* 0x07 - C7 - Control 3 in TDA9855, Control 4 in TDA9850 */
/* Common to both TDA9855 and TDA9850: */
/* lower 4 bits control input gain from -3.5dB (0x0) to 4dB (0xF)
 * in .5dB steps -  0dB is 0x7 */

/* 0x08, 0x09 - A1 and A2 (read/write) */
/* Common to both TDA9855 and TDA9850: */
/* lower 5 bites are wideband and spectral expander alignment
 * from 0x00 to 0x1f - nominal at 0x0f and 0x10 (read/write) */
#define TDA985x_STP
#define TDA985x_SAPP
#define TDA985x_STS

/* 0x0a - A3 */
/* Common to both TDA9855 and TDA9850: */
/* lower 3 bits control timing current for alignment: -30% (0x0), -20% (0x1),
 * -10% (0x2), nominal (0x3), +10% (0x6), +20% (0x5), +30% (0x4) */
#define TDA985x_ADJ

static int tda9855_volume(int val) {}
static int tda9855_bass(int val)   {}
static int tda9855_treble(int val) {}

static int  tda985x_getrxsubchans(struct CHIPSTATE *chip)
{}

static void tda985x_setaudmode(struct CHIPSTATE *chip, int mode)
{}


/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tda9873h               */

/* Subaddresses for TDA9873H */

#define TDA9873_SW
#define TDA9873_AD
#define TDA9873_PT

/* Subaddress 0x00: Switching Data
 * B7..B0:
 *
 * B1, B0: Input source selection
 *  0,  0  internal
 *  1,  0  external stereo
 *  0,  1  external mono
 */
#define TDA9873_INP_MASK
#define TDA9873_INTERNAL
#define TDA9873_EXT_STEREO
#define TDA9873_EXT_MONO

/*    B3, B2: output signal select
 * B4    : transmission mode
 *  0, 0, 1   Mono
 *  1, 0, 0   Stereo
 *  1, 1, 1   Stereo (reversed channel)
 *  0, 0, 0   Dual AB
 *  0, 0, 1   Dual AA
 *  0, 1, 0   Dual BB
 *  0, 1, 1   Dual BA
 */

#define TDA9873_TR_MASK
#define TDA9873_TR_MONO
#define TDA9873_TR_STEREO
#define TDA9873_TR_REVERSE
#define TDA9873_TR_DUALA
#define TDA9873_TR_DUALB
#define TDA9873_TR_DUALAB

/* output level controls
 * B5:  output level switch (0 = reduced gain, 1 = normal gain)
 * B6:  mute                (1 = muted)
 * B7:  auto-mute           (1 = auto-mute enabled)
 */

#define TDA9873_GAIN_NORMAL
#define TDA9873_MUTE
#define TDA9873_AUTOMUTE

/* Subaddress 0x01:  Adjust/standard */

/* Lower 4 bits (C3..C0) control stereo adjustment on R channel (-0.6 - +0.7 dB)
 * Recommended value is +0 dB
 */

#define TDA9873_STEREO_ADJ

/* Bits C6..C4 control FM stantard
 * C6, C5, C4
 *  0,  0,  0   B/G (PAL FM)
 *  0,  0,  1   M
 *  0,  1,  0   D/K(1)
 *  0,  1,  1   D/K(2)
 *  1,  0,  0   D/K(3)
 *  1,  0,  1   I
 */
#define TDA9873_BG
#define TDA9873_M
#define TDA9873_DK1
#define TDA9873_DK2
#define TDA9873_DK3
#define TDA9873_I

/* C7 controls identification response time (1=fast/0=normal)
 */
#define TDA9873_IDR_NORM
#define TDA9873_IDR_FAST


/* Subaddress 0x02: Port data */

/* E1, E0   free programmable ports P1/P2
    0,  0   both ports low
    0,  1   P1 high
    1,  0   P2 high
    1,  1   both ports high
*/

#define TDA9873_PORTS

/* E2: test port */
#define TDA9873_TST_PORT

/* E5..E3 control mono output channel (together with transmission mode bit B4)
 *
 * E5 E4 E3 B4     OUTM
 *  0  0  0  0     mono
 *  0  0  1  0     DUAL B
 *  0  1  0  1     mono (from stereo decoder)
 */
#define TDA9873_MOUT_MONO
#define TDA9873_MOUT_FMONO
#define TDA9873_MOUT_DUALA
#define TDA9873_MOUT_DUALB
#define TDA9873_MOUT_ST
#define TDA9873_MOUT_EXTM
#define TDA9873_MOUT_EXTL
#define TDA9873_MOUT_EXTR
#define TDA9873_MOUT_EXTLR
#define TDA9873_MOUT_MUTE

/* Status bits: (chip read) */
#define TDA9873_PONR
#define TDA9873_STEREO
#define TDA9873_DUAL

static int tda9873_getrxsubchans(struct CHIPSTATE *chip)
{}

static void tda9873_setaudmode(struct CHIPSTATE *chip, int mode)
{}

static int tda9873_checkit(struct CHIPSTATE *chip)
{}


/* ---------------------------------------------------------------------- */
/* audio chip description - defines+functions for tda9874h and tda9874a   */
/* Dariusz Kowalewski <[email protected]>                                 */

/* Subaddresses for TDA9874H and TDA9874A (slave rx) */
#define TDA9874A_AGCGR
#define TDA9874A_GCONR
#define TDA9874A_MSR
#define TDA9874A_C1FRA
#define TDA9874A_C1FRB
#define TDA9874A_C1FRC
#define TDA9874A_C2FRA
#define TDA9874A_C2FRB
#define TDA9874A_C2FRC
#define TDA9874A_DCR
#define TDA9874A_FMER
#define TDA9874A_FMMR
#define TDA9874A_C1OLAR
#define TDA9874A_C2OLAR
#define TDA9874A_NCONR
#define TDA9874A_NOLAR
#define TDA9874A_NLELR
#define TDA9874A_NUELR
#define TDA9874A_AMCONR
#define TDA9874A_SDACOSR
#define TDA9874A_AOSR
#define TDA9874A_DAICONR
#define TDA9874A_I2SOSR
#define TDA9874A_I2SOLAR
#define TDA9874A_MDACOSR
#define TDA9874A_ESP

/* Subaddresses for TDA9874H and TDA9874A (slave tx) */
#define TDA9874A_DSR
#define TDA9874A_NSR
#define TDA9874A_NECR
#define TDA9874A_DR1
#define TDA9874A_DR2
#define TDA9874A_LLRA
#define TDA9874A_LLRB
#define TDA9874A_SIFLR
#define TDA9874A_TR2
#define TDA9874A_TR1
#define TDA9874A_DIC
#define TDA9874A_SIC


static int tda9874a_mode =;		/* 0: A2, 1: NICAM */
static int tda9874a_GCONR =;	/* default config. input pin: SIFSEL=0 */
static int tda9874a_NCONR =;	/* default NICAM config.: AMSEL=0,AMUTE=1 */
static int tda9874a_ESP =;		/* default standard: NICAM D/K */
static int tda9874a_dic =;		/* device id. code */

/* insmod options for tda9874a */
static unsigned int tda9874a_SIF   =;
static unsigned int tda9874a_AMSEL =;
static unsigned int tda9874a_STD   =;
module_param(tda9874a_SIF, int, 0444);
module_param(tda9874a_AMSEL, int, 0444);
module_param(tda9874a_STD, int, 0444);

/*
 * initialization table for tda9874 decoder:
 *  - carrier 1 freq. registers (3 bytes)
 *  - carrier 2 freq. registers (3 bytes)
 *  - demudulator config register
 *  - FM de-emphasis register (slow identification mode)
 * Note: frequency registers must be written in single i2c transfer.
 */
static struct tda9874a_MODES {} tda9874a_modelist[9] =;

static int tda9874a_setup(struct CHIPSTATE *chip)
{}

static int tda9874a_getrxsubchans(struct CHIPSTATE *chip)
{}

static void tda9874a_setaudmode(struct CHIPSTATE *chip, int mode)
{}

static int tda9874a_checkit(struct CHIPSTATE *chip)
{}

static int tda9874a_initialize(struct CHIPSTATE *chip)
{}

/* ---------------------------------------------------------------------- */
/* audio chip description - defines+functions for tda9875                 */
/* The TDA9875 is made by Philips Semiconductor
 * http://www.semiconductors.philips.com
 * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
 *
 */

/* subaddresses for TDA9875 */
#define TDA9875_MUT
#define TDA9875_CFG
#define TDA9875_DACOS
#define TDA9875_LOSR

#define TDA9875_CH1V
#define TDA9875_CH2V
#define TDA9875_SC1
#define TDA9875_SC2

#define TDA9875_ADCIS
#define TDA9875_AER
#define TDA9875_MCS
#define TDA9875_MVL
#define TDA9875_MVR
#define TDA9875_MBA
#define TDA9875_MTR
#define TDA9875_ACS
#define TDA9875_AVL
#define TDA9875_AVR
#define TDA9875_ABA
#define TDA9875_ATR

#define TDA9875_MSR
#define TDA9875_C1MSB
#define TDA9875_C1MIB
#define TDA9875_C1LSB
#define TDA9875_C2MSB
#define TDA9875_C2MIB
#define TDA9875_C2LSB
#define TDA9875_DCR
#define TDA9875_DEEM
#define TDA9875_FMAT

/* values */
#define TDA9875_MUTE_ON
#define TDA9875_MUTE_OFF

static int tda9875_initialize(struct CHIPSTATE *chip)
{}

static int tda9875_volume(int val) {}
static int tda9875_bass(int val) {}
static int tda9875_treble(int val) {}

/* ----------------------------------------------------------------------- */


/* *********************** *
 * i2c interface functions *
 * *********************** */

static int tda9875_checkit(struct CHIPSTATE *chip)
{}

/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tea6420                */

#define TEA6300_VL
#define TEA6300_VR
#define TEA6300_BA
#define TEA6300_TR
#define TEA6300_FA
#define TEA6300_S
				 /* values for those registers: */
#define TEA6300_S_SA
#define TEA6300_S_SB
#define TEA6300_S_SC
#define TEA6300_S_GMU

#define TEA6320_V
#define TEA6320_FFR
#define TEA6320_FFL
#define TEA6320_FRR
#define TEA6320_FRL
#define TEA6320_BA
#define TEA6320_TR
#define TEA6320_S
				 /* values for those registers: */
#define TEA6320_S_SA
#define TEA6320_S_SB
#define TEA6320_S_SC
#define TEA6320_S_SD
#define TEA6320_S_GMU

#define TEA6420_S_SA
#define TEA6420_S_SB
#define TEA6420_S_SC
#define TEA6420_S_SD
#define TEA6420_S_SE
#define TEA6420_S_GMU

static int tea6300_shift10(int val) {}
static int tea6300_shift12(int val) {}

/* Assumes 16bit input (values 0x3f to 0x0c are unique, values less than */
/* 0x0c mirror those immediately higher) */
static int tea6320_volume(int val) {}
static int tea6320_shift11(int val) {}
static int tea6320_initialize(struct CHIPSTATE * chip)
{}


/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tda8425                */

#define TDA8425_VL
#define TDA8425_VR
#define TDA8425_BA
#define TDA8425_TR
#define TDA8425_S1
				 /* values for those registers: */
#define TDA8425_S1_OFF
#define TDA8425_S1_CH1
#define TDA8425_S1_CH2
#define TDA8425_S1_MU
#define TDA8425_S1_STEREO
#define TDA8425_S1_STEREO_SPATIAL
#define TDA8425_S1_STEREO_LINEAR
#define TDA8425_S1_STEREO_PSEUDO
#define TDA8425_S1_STEREO_MONO
#define TDA8425_S1_ML
#define TDA8425_S1_ML_SOUND_A
#define TDA8425_S1_ML_SOUND_B
#define TDA8425_S1_ML_STEREO
#define TDA8425_S1_IS


static int tda8425_shift10(int val) {}
static int tda8425_shift12(int val) {}

static void tda8425_setaudmode(struct CHIPSTATE *chip, int mode)
{}


/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for pic16c54 (PV951)       */

/* the registers of 16C54, I2C sub address. */
#define PIC16C54_REG_KEY_CODE
#define PIC16C54_REG_MISC

/* bit definition of the RESET register, I2C data. */
#define PIC16C54_MISC_RESET_REMOTE_CTL
					    /*        code of remote controller */
#define PIC16C54_MISC_MTS_MAIN
#define PIC16C54_MISC_MTS_SAP
#define PIC16C54_MISC_MTS_BOTH
#define PIC16C54_MISC_SND_MUTE
#define PIC16C54_MISC_SND_NOTMUTE
#define PIC16C54_MISC_SWITCH_TUNER
#define PIC16C54_MISC_SWITCH_LINE

/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for TA8874Z                */

/* write 1st byte */
#define TA8874Z_LED_STE
#define TA8874Z_LED_BIL
#define TA8874Z_LED_EXT
#define TA8874Z_MONO_SET
#define TA8874Z_MUTE
#define TA8874Z_F_MONO
#define TA8874Z_MODE_SUB
#define TA8874Z_MODE_MAIN

/* write 2nd byte */
/*#define TA8874Z_TI	0x80  */ /* test mode */
#define TA8874Z_SEPARATION
#define TA8874Z_SEPARATION_DEFAULT

/* read */
#define TA8874Z_B1
#define TA8874Z_B0
#define TA8874Z_CHAG_FLAG

/*
 *        B1 B0
 * mono    L  H
 * stereo  L  L
 * BIL     H  L
 */
static int ta8874z_getrxsubchans(struct CHIPSTATE *chip)
{}

static audiocmd ta8874z_stereo =;
static audiocmd ta8874z_mono =;
static audiocmd ta8874z_main =;
static audiocmd ta8874z_sub =;
static audiocmd ta8874z_both =;

static void ta8874z_setaudmode(struct CHIPSTATE *chip, int mode)
{}

static int ta8874z_checkit(struct CHIPSTATE *chip)
{}

/* ---------------------------------------------------------------------- */
/* audio chip descriptions - struct CHIPDESC                              */

/* insmod options to enable/disable individual audio chips */
static int tda8425  =;
static int tda9840  =;
static int tda9850  =;
static int tda9855  =;
static int tda9873  =;
static int tda9874a =;
static int tda9875  =;
static int tea6300;	/* default 0 - address clash with msp34xx */
static int tea6320;	/* default 0 - address clash with msp34xx */
static int tea6420  =;
static int pic16c54 =;
static int ta8874z;	/* default 0 - address clash with tda9840 */

module_param(tda8425, int, 0444);
module_param(tda9840, int, 0444);
module_param(tda9850, int, 0444);
module_param(tda9855, int, 0444);
module_param(tda9873, int, 0444);
module_param(tda9874a, int, 0444);
module_param(tda9875, int, 0444);
module_param(tea6300, int, 0444);
module_param(tea6320, int, 0444);
module_param(tea6420, int, 0444);
module_param(pic16c54, int, 0444);
module_param(ta8874z, int, 0444);

static struct CHIPDESC chiplist[] =;


/* ---------------------------------------------------------------------- */

static int tvaudio_s_ctrl(struct v4l2_ctrl *ctrl)
{}


/* ---------------------------------------------------------------------- */
/* video4linux interface                                                  */

static int tvaudio_s_radio(struct v4l2_subdev *sd)
{}

static int tvaudio_s_routing(struct v4l2_subdev *sd,
			     u32 input, u32 output, u32 config)
{}

static int tvaudio_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
{}

static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{}

static int tvaudio_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{}

static int tvaudio_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *freq)
{}

static int tvaudio_log_status(struct v4l2_subdev *sd)
{}

/* ----------------------------------------------------------------------- */

static const struct v4l2_ctrl_ops tvaudio_ctrl_ops =;

static const struct v4l2_subdev_core_ops tvaudio_core_ops =;

static const struct v4l2_subdev_tuner_ops tvaudio_tuner_ops =;

static const struct v4l2_subdev_audio_ops tvaudio_audio_ops =;

static const struct v4l2_subdev_video_ops tvaudio_video_ops =;

static const struct v4l2_subdev_ops tvaudio_ops =;

/* ----------------------------------------------------------------------- */


/* i2c registration                                                       */

static int tvaudio_probe(struct i2c_client *client)
{}

static void tvaudio_remove(struct i2c_client *client)
{}

/* This driver supports many devices and the idea is to let the driver
   detect which device is present. So rather than listing all supported
   devices here, we pretend to support a single, fake device type. */
static const struct i2c_device_id tvaudio_id[] =;
MODULE_DEVICE_TABLE(i2c, tvaudio_id);

static struct i2c_driver tvaudio_driver =;

module_i2c_driver();