1cb7a01acSMauro Carvalho Chehab /* 2cb7a01acSMauro Carvalho Chehab * saa717x - Philips SAA717xHL video decoder driver 3cb7a01acSMauro Carvalho Chehab * 4cb7a01acSMauro Carvalho Chehab * Based on the saa7115 driver 5cb7a01acSMauro Carvalho Chehab * 6cb7a01acSMauro Carvalho Chehab * Changes by Ohta Kyuma <alpha292@bremen.or.jp> 7cb7a01acSMauro Carvalho Chehab * - Apply to SAA717x,NEC uPD64031,uPD64083. (1/31/2004) 8cb7a01acSMauro Carvalho Chehab * 9cb7a01acSMauro Carvalho Chehab * Changes by T.Adachi (tadachi@tadachi-net.com) 10cb7a01acSMauro Carvalho Chehab * - support audio, video scaler etc, and checked the initialize sequence. 11cb7a01acSMauro Carvalho Chehab * 12cb7a01acSMauro Carvalho Chehab * Cleaned up by Hans Verkuil <hverkuil@xs4all.nl> 13cb7a01acSMauro Carvalho Chehab * 14cb7a01acSMauro Carvalho Chehab * Note: this is a reversed engineered driver based on captures from 15cb7a01acSMauro Carvalho Chehab * the I2C bus under Windows. This chip is very similar to the saa7134, 16cb7a01acSMauro Carvalho Chehab * though. Unfortunately, this driver is currently only working for NTSC. 17cb7a01acSMauro Carvalho Chehab * 18cb7a01acSMauro Carvalho Chehab * This program is free software; you can redistribute it and/or modify 19cb7a01acSMauro Carvalho Chehab * it under the terms of the GNU General Public License as published by 20cb7a01acSMauro Carvalho Chehab * the Free Software Foundation; either version 2 of the License, or 21cb7a01acSMauro Carvalho Chehab * (at your option) any later version. 22cb7a01acSMauro Carvalho Chehab * 23cb7a01acSMauro Carvalho Chehab * This program is distributed in the hope that it will be useful, 24cb7a01acSMauro Carvalho Chehab * but WITHOUT ANY WARRANTY; without even the implied warranty of 25cb7a01acSMauro Carvalho Chehab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26cb7a01acSMauro Carvalho Chehab * GNU General Public License for more details. 27cb7a01acSMauro Carvalho Chehab * 28cb7a01acSMauro Carvalho Chehab * You should have received a copy of the GNU General Public License 29cb7a01acSMauro Carvalho Chehab * along with this program; if not, write to the Free Software 30cb7a01acSMauro Carvalho Chehab * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 31cb7a01acSMauro Carvalho Chehab */ 32cb7a01acSMauro Carvalho Chehab 33cb7a01acSMauro Carvalho Chehab #include <linux/module.h> 34cb7a01acSMauro Carvalho Chehab #include <linux/kernel.h> 35cb7a01acSMauro Carvalho Chehab #include <linux/slab.h> 36cb7a01acSMauro Carvalho Chehab #include <linux/sched.h> 37cb7a01acSMauro Carvalho Chehab 38cb7a01acSMauro Carvalho Chehab #include <linux/videodev2.h> 39cb7a01acSMauro Carvalho Chehab #include <linux/i2c.h> 40cb7a01acSMauro Carvalho Chehab #include <media/v4l2-device.h> 41cb7a01acSMauro Carvalho Chehab #include <media/v4l2-ctrls.h> 42cb7a01acSMauro Carvalho Chehab 43cb7a01acSMauro Carvalho Chehab MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); 44cb7a01acSMauro Carvalho Chehab MODULE_AUTHOR("K. Ohta, T. Adachi, Hans Verkuil"); 45cb7a01acSMauro Carvalho Chehab MODULE_LICENSE("GPL"); 46cb7a01acSMauro Carvalho Chehab 47cb7a01acSMauro Carvalho Chehab static int debug; 48cb7a01acSMauro Carvalho Chehab module_param(debug, int, 0644); 49cb7a01acSMauro Carvalho Chehab MODULE_PARM_DESC(debug, "Debug level (0-1)"); 50cb7a01acSMauro Carvalho Chehab 51cb7a01acSMauro Carvalho Chehab /* 52cb7a01acSMauro Carvalho Chehab * Generic i2c probe 53cb7a01acSMauro Carvalho Chehab * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 54cb7a01acSMauro Carvalho Chehab */ 55cb7a01acSMauro Carvalho Chehab 56cb7a01acSMauro Carvalho Chehab struct saa717x_state { 57cb7a01acSMauro Carvalho Chehab struct v4l2_subdev sd; 58cb7a01acSMauro Carvalho Chehab struct v4l2_ctrl_handler hdl; 59cb7a01acSMauro Carvalho Chehab v4l2_std_id std; 60cb7a01acSMauro Carvalho Chehab int input; 61cb7a01acSMauro Carvalho Chehab int enable; 62cb7a01acSMauro Carvalho Chehab int radio; 63cb7a01acSMauro Carvalho Chehab int playback; 64cb7a01acSMauro Carvalho Chehab int audio; 65cb7a01acSMauro Carvalho Chehab int tuner_audio_mode; 66cb7a01acSMauro Carvalho Chehab int audio_main_mute; 67cb7a01acSMauro Carvalho Chehab int audio_main_vol_r; 68cb7a01acSMauro Carvalho Chehab int audio_main_vol_l; 69cb7a01acSMauro Carvalho Chehab u16 audio_main_bass; 70cb7a01acSMauro Carvalho Chehab u16 audio_main_treble; 71cb7a01acSMauro Carvalho Chehab u16 audio_main_volume; 72cb7a01acSMauro Carvalho Chehab u16 audio_main_balance; 73cb7a01acSMauro Carvalho Chehab int audio_input; 74cb7a01acSMauro Carvalho Chehab }; 75cb7a01acSMauro Carvalho Chehab 76cb7a01acSMauro Carvalho Chehab static inline struct saa717x_state *to_state(struct v4l2_subdev *sd) 77cb7a01acSMauro Carvalho Chehab { 78cb7a01acSMauro Carvalho Chehab return container_of(sd, struct saa717x_state, sd); 79cb7a01acSMauro Carvalho Chehab } 80cb7a01acSMauro Carvalho Chehab 81cb7a01acSMauro Carvalho Chehab static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) 82cb7a01acSMauro Carvalho Chehab { 83cb7a01acSMauro Carvalho Chehab return &container_of(ctrl->handler, struct saa717x_state, hdl)->sd; 84cb7a01acSMauro Carvalho Chehab } 85cb7a01acSMauro Carvalho Chehab 86cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 87cb7a01acSMauro Carvalho Chehab 88cb7a01acSMauro Carvalho Chehab /* for audio mode */ 89cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_MONO 0 /* LL */ 90cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_STEREO 1 /* LR */ 91cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_LANG1 2 /* LL */ 92cb7a01acSMauro Carvalho Chehab #define TUNER_AUDIO_LANG2 3 /* RR */ 93cb7a01acSMauro Carvalho Chehab 94cb7a01acSMauro Carvalho Chehab #define SAA717X_NTSC_WIDTH (704) 95cb7a01acSMauro Carvalho Chehab #define SAA717X_NTSC_HEIGHT (480) 96cb7a01acSMauro Carvalho Chehab 97cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 98cb7a01acSMauro Carvalho Chehab 99cb7a01acSMauro Carvalho Chehab static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value) 100cb7a01acSMauro Carvalho Chehab { 101cb7a01acSMauro Carvalho Chehab struct i2c_client *client = v4l2_get_subdevdata(sd); 102cb7a01acSMauro Carvalho Chehab struct i2c_adapter *adap = client->adapter; 103cb7a01acSMauro Carvalho Chehab int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488; 104cb7a01acSMauro Carvalho Chehab unsigned char mm1[6]; 105cb7a01acSMauro Carvalho Chehab struct i2c_msg msg; 106cb7a01acSMauro Carvalho Chehab 107cb7a01acSMauro Carvalho Chehab msg.flags = 0; 108cb7a01acSMauro Carvalho Chehab msg.addr = client->addr; 109cb7a01acSMauro Carvalho Chehab mm1[0] = (reg >> 8) & 0xff; 110cb7a01acSMauro Carvalho Chehab mm1[1] = reg & 0xff; 111cb7a01acSMauro Carvalho Chehab 112cb7a01acSMauro Carvalho Chehab if (fw_addr) { 113cb7a01acSMauro Carvalho Chehab mm1[4] = (value >> 16) & 0xff; 114cb7a01acSMauro Carvalho Chehab mm1[3] = (value >> 8) & 0xff; 115cb7a01acSMauro Carvalho Chehab mm1[2] = value & 0xff; 116cb7a01acSMauro Carvalho Chehab } else { 117cb7a01acSMauro Carvalho Chehab mm1[2] = value & 0xff; 118cb7a01acSMauro Carvalho Chehab } 119cb7a01acSMauro Carvalho Chehab msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */ 120cb7a01acSMauro Carvalho Chehab msg.buf = mm1; 121cb7a01acSMauro Carvalho Chehab v4l2_dbg(2, debug, sd, "wrote: reg 0x%03x=%08x\n", reg, value); 122cb7a01acSMauro Carvalho Chehab return i2c_transfer(adap, &msg, 1) == 1; 123cb7a01acSMauro Carvalho Chehab } 124cb7a01acSMauro Carvalho Chehab 125cb7a01acSMauro Carvalho Chehab static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data) 126cb7a01acSMauro Carvalho Chehab { 127cb7a01acSMauro Carvalho Chehab while (data[0] || data[1]) { 128cb7a01acSMauro Carvalho Chehab saa717x_write(sd, data[0], data[1]); 129cb7a01acSMauro Carvalho Chehab data += 2; 130cb7a01acSMauro Carvalho Chehab } 131cb7a01acSMauro Carvalho Chehab } 132cb7a01acSMauro Carvalho Chehab 133cb7a01acSMauro Carvalho Chehab static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg) 134cb7a01acSMauro Carvalho Chehab { 135cb7a01acSMauro Carvalho Chehab struct i2c_client *client = v4l2_get_subdevdata(sd); 136cb7a01acSMauro Carvalho Chehab struct i2c_adapter *adap = client->adapter; 137cb7a01acSMauro Carvalho Chehab int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528; 138cb7a01acSMauro Carvalho Chehab unsigned char mm1[2]; 139cb7a01acSMauro Carvalho Chehab unsigned char mm2[4] = { 0, 0, 0, 0 }; 140cb7a01acSMauro Carvalho Chehab struct i2c_msg msgs[2]; 141cb7a01acSMauro Carvalho Chehab u32 value; 142cb7a01acSMauro Carvalho Chehab 143cb7a01acSMauro Carvalho Chehab msgs[0].flags = 0; 144cb7a01acSMauro Carvalho Chehab msgs[1].flags = I2C_M_RD; 145cb7a01acSMauro Carvalho Chehab msgs[0].addr = msgs[1].addr = client->addr; 146cb7a01acSMauro Carvalho Chehab mm1[0] = (reg >> 8) & 0xff; 147cb7a01acSMauro Carvalho Chehab mm1[1] = reg & 0xff; 148cb7a01acSMauro Carvalho Chehab msgs[0].len = 2; 149cb7a01acSMauro Carvalho Chehab msgs[0].buf = mm1; 150cb7a01acSMauro Carvalho Chehab msgs[1].len = fw_addr ? 3 : 1; /* Multibyte Registers contains *only* 3 bytes */ 151cb7a01acSMauro Carvalho Chehab msgs[1].buf = mm2; 152cb7a01acSMauro Carvalho Chehab i2c_transfer(adap, msgs, 2); 153cb7a01acSMauro Carvalho Chehab 154cb7a01acSMauro Carvalho Chehab if (fw_addr) 1554c7ba408SMauro Carvalho Chehab value = (mm2[2] << 16) | (mm2[1] << 8) | mm2[0]; 156cb7a01acSMauro Carvalho Chehab else 1574c7ba408SMauro Carvalho Chehab value = mm2[0]; 158cb7a01acSMauro Carvalho Chehab 159cb7a01acSMauro Carvalho Chehab v4l2_dbg(2, debug, sd, "read: reg 0x%03x=0x%08x\n", reg, value); 160cb7a01acSMauro Carvalho Chehab return value; 161cb7a01acSMauro Carvalho Chehab } 162cb7a01acSMauro Carvalho Chehab 163cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 164cb7a01acSMauro Carvalho Chehab 165cb7a01acSMauro Carvalho Chehab static u32 reg_init_initialize[] = 166cb7a01acSMauro Carvalho Chehab { 167cb7a01acSMauro Carvalho Chehab /* from linux driver */ 168cb7a01acSMauro Carvalho Chehab 0x101, 0x008, /* Increment delay */ 169cb7a01acSMauro Carvalho Chehab 170cb7a01acSMauro Carvalho Chehab 0x103, 0x000, /* Analog input control 2 */ 171cb7a01acSMauro Carvalho Chehab 0x104, 0x090, /* Analog input control 3 */ 172cb7a01acSMauro Carvalho Chehab 0x105, 0x090, /* Analog input control 4 */ 173cb7a01acSMauro Carvalho Chehab 0x106, 0x0eb, /* Horizontal sync start */ 174cb7a01acSMauro Carvalho Chehab 0x107, 0x0e0, /* Horizontal sync stop */ 175cb7a01acSMauro Carvalho Chehab 0x109, 0x055, /* Luminance control */ 176cb7a01acSMauro Carvalho Chehab 177cb7a01acSMauro Carvalho Chehab 0x10f, 0x02a, /* Chroma gain control */ 178cb7a01acSMauro Carvalho Chehab 0x110, 0x000, /* Chroma control 2 */ 179cb7a01acSMauro Carvalho Chehab 180cb7a01acSMauro Carvalho Chehab 0x114, 0x045, /* analog/ADC */ 181cb7a01acSMauro Carvalho Chehab 182cb7a01acSMauro Carvalho Chehab 0x118, 0x040, /* RAW data gain */ 183cb7a01acSMauro Carvalho Chehab 0x119, 0x080, /* RAW data offset */ 184cb7a01acSMauro Carvalho Chehab 185cb7a01acSMauro Carvalho Chehab 0x044, 0x000, /* VBI horizontal input window start (L) TASK A */ 186cb7a01acSMauro Carvalho Chehab 0x045, 0x000, /* VBI horizontal input window start (H) TASK A */ 187cb7a01acSMauro Carvalho Chehab 0x046, 0x0cf, /* VBI horizontal input window stop (L) TASK A */ 188cb7a01acSMauro Carvalho Chehab 0x047, 0x002, /* VBI horizontal input window stop (H) TASK A */ 189cb7a01acSMauro Carvalho Chehab 190cb7a01acSMauro Carvalho Chehab 0x049, 0x000, /* VBI vertical input window start (H) TASK A */ 191cb7a01acSMauro Carvalho Chehab 192cb7a01acSMauro Carvalho Chehab 0x04c, 0x0d0, /* VBI horizontal output length (L) TASK A */ 193cb7a01acSMauro Carvalho Chehab 0x04d, 0x002, /* VBI horizontal output length (H) TASK A */ 194cb7a01acSMauro Carvalho Chehab 195cb7a01acSMauro Carvalho Chehab 0x064, 0x080, /* Lumina brightness TASK A */ 196cb7a01acSMauro Carvalho Chehab 0x065, 0x040, /* Luminance contrast TASK A */ 197cb7a01acSMauro Carvalho Chehab 0x066, 0x040, /* Chroma saturation TASK A */ 198cb7a01acSMauro Carvalho Chehab /* 067H: Reserved */ 199cb7a01acSMauro Carvalho Chehab 0x068, 0x000, /* VBI horizontal scaling increment (L) TASK A */ 200cb7a01acSMauro Carvalho Chehab 0x069, 0x004, /* VBI horizontal scaling increment (H) TASK A */ 201cb7a01acSMauro Carvalho Chehab 0x06a, 0x000, /* VBI phase offset TASK A */ 202cb7a01acSMauro Carvalho Chehab 203cb7a01acSMauro Carvalho Chehab 0x06e, 0x000, /* Horizontal phase offset Luma TASK A */ 204cb7a01acSMauro Carvalho Chehab 0x06f, 0x000, /* Horizontal phase offset Chroma TASK A */ 205cb7a01acSMauro Carvalho Chehab 206cb7a01acSMauro Carvalho Chehab 0x072, 0x000, /* Vertical filter mode TASK A */ 207cb7a01acSMauro Carvalho Chehab 208cb7a01acSMauro Carvalho Chehab 0x084, 0x000, /* VBI horizontal input window start (L) TAKS B */ 209cb7a01acSMauro Carvalho Chehab 0x085, 0x000, /* VBI horizontal input window start (H) TAKS B */ 210cb7a01acSMauro Carvalho Chehab 0x086, 0x0cf, /* VBI horizontal input window stop (L) TAKS B */ 211cb7a01acSMauro Carvalho Chehab 0x087, 0x002, /* VBI horizontal input window stop (H) TAKS B */ 212cb7a01acSMauro Carvalho Chehab 213cb7a01acSMauro Carvalho Chehab 0x089, 0x000, /* VBI vertical input window start (H) TAKS B */ 214cb7a01acSMauro Carvalho Chehab 215cb7a01acSMauro Carvalho Chehab 0x08c, 0x0d0, /* VBI horizontal output length (L) TASK B */ 216cb7a01acSMauro Carvalho Chehab 0x08d, 0x002, /* VBI horizontal output length (H) TASK B */ 217cb7a01acSMauro Carvalho Chehab 218cb7a01acSMauro Carvalho Chehab 0x0a4, 0x080, /* Lumina brightness TASK B */ 219cb7a01acSMauro Carvalho Chehab 0x0a5, 0x040, /* Luminance contrast TASK B */ 220cb7a01acSMauro Carvalho Chehab 0x0a6, 0x040, /* Chroma saturation TASK B */ 221cb7a01acSMauro Carvalho Chehab /* 0A7H reserved */ 222cb7a01acSMauro Carvalho Chehab 0x0a8, 0x000, /* VBI horizontal scaling increment (L) TASK B */ 223cb7a01acSMauro Carvalho Chehab 0x0a9, 0x004, /* VBI horizontal scaling increment (H) TASK B */ 224cb7a01acSMauro Carvalho Chehab 0x0aa, 0x000, /* VBI phase offset TASK B */ 225cb7a01acSMauro Carvalho Chehab 226cb7a01acSMauro Carvalho Chehab 0x0ae, 0x000, /* Horizontal phase offset Luma TASK B */ 227cb7a01acSMauro Carvalho Chehab 0x0af, 0x000, /*Horizontal phase offset Chroma TASK B */ 228cb7a01acSMauro Carvalho Chehab 229cb7a01acSMauro Carvalho Chehab 0x0b2, 0x000, /* Vertical filter mode TASK B */ 230cb7a01acSMauro Carvalho Chehab 231cb7a01acSMauro Carvalho Chehab 0x00c, 0x000, /* Start point GREEN path */ 232cb7a01acSMauro Carvalho Chehab 0x00d, 0x000, /* Start point BLUE path */ 233cb7a01acSMauro Carvalho Chehab 0x00e, 0x000, /* Start point RED path */ 234cb7a01acSMauro Carvalho Chehab 235cb7a01acSMauro Carvalho Chehab 0x010, 0x010, /* GREEN path gamma curve --- */ 236cb7a01acSMauro Carvalho Chehab 0x011, 0x020, 237cb7a01acSMauro Carvalho Chehab 0x012, 0x030, 238cb7a01acSMauro Carvalho Chehab 0x013, 0x040, 239cb7a01acSMauro Carvalho Chehab 0x014, 0x050, 240cb7a01acSMauro Carvalho Chehab 0x015, 0x060, 241cb7a01acSMauro Carvalho Chehab 0x016, 0x070, 242cb7a01acSMauro Carvalho Chehab 0x017, 0x080, 243cb7a01acSMauro Carvalho Chehab 0x018, 0x090, 244cb7a01acSMauro Carvalho Chehab 0x019, 0x0a0, 245cb7a01acSMauro Carvalho Chehab 0x01a, 0x0b0, 246cb7a01acSMauro Carvalho Chehab 0x01b, 0x0c0, 247cb7a01acSMauro Carvalho Chehab 0x01c, 0x0d0, 248cb7a01acSMauro Carvalho Chehab 0x01d, 0x0e0, 249cb7a01acSMauro Carvalho Chehab 0x01e, 0x0f0, 250cb7a01acSMauro Carvalho Chehab 0x01f, 0x0ff, /* --- GREEN path gamma curve */ 251cb7a01acSMauro Carvalho Chehab 252cb7a01acSMauro Carvalho Chehab 0x020, 0x010, /* BLUE path gamma curve --- */ 253cb7a01acSMauro Carvalho Chehab 0x021, 0x020, 254cb7a01acSMauro Carvalho Chehab 0x022, 0x030, 255cb7a01acSMauro Carvalho Chehab 0x023, 0x040, 256cb7a01acSMauro Carvalho Chehab 0x024, 0x050, 257cb7a01acSMauro Carvalho Chehab 0x025, 0x060, 258cb7a01acSMauro Carvalho Chehab 0x026, 0x070, 259cb7a01acSMauro Carvalho Chehab 0x027, 0x080, 260cb7a01acSMauro Carvalho Chehab 0x028, 0x090, 261cb7a01acSMauro Carvalho Chehab 0x029, 0x0a0, 262cb7a01acSMauro Carvalho Chehab 0x02a, 0x0b0, 263cb7a01acSMauro Carvalho Chehab 0x02b, 0x0c0, 264cb7a01acSMauro Carvalho Chehab 0x02c, 0x0d0, 265cb7a01acSMauro Carvalho Chehab 0x02d, 0x0e0, 266cb7a01acSMauro Carvalho Chehab 0x02e, 0x0f0, 267cb7a01acSMauro Carvalho Chehab 0x02f, 0x0ff, /* --- BLUE path gamma curve */ 268cb7a01acSMauro Carvalho Chehab 269cb7a01acSMauro Carvalho Chehab 0x030, 0x010, /* RED path gamma curve --- */ 270cb7a01acSMauro Carvalho Chehab 0x031, 0x020, 271cb7a01acSMauro Carvalho Chehab 0x032, 0x030, 272cb7a01acSMauro Carvalho Chehab 0x033, 0x040, 273cb7a01acSMauro Carvalho Chehab 0x034, 0x050, 274cb7a01acSMauro Carvalho Chehab 0x035, 0x060, 275cb7a01acSMauro Carvalho Chehab 0x036, 0x070, 276cb7a01acSMauro Carvalho Chehab 0x037, 0x080, 277cb7a01acSMauro Carvalho Chehab 0x038, 0x090, 278cb7a01acSMauro Carvalho Chehab 0x039, 0x0a0, 279cb7a01acSMauro Carvalho Chehab 0x03a, 0x0b0, 280cb7a01acSMauro Carvalho Chehab 0x03b, 0x0c0, 281cb7a01acSMauro Carvalho Chehab 0x03c, 0x0d0, 282cb7a01acSMauro Carvalho Chehab 0x03d, 0x0e0, 283cb7a01acSMauro Carvalho Chehab 0x03e, 0x0f0, 284cb7a01acSMauro Carvalho Chehab 0x03f, 0x0ff, /* --- RED path gamma curve */ 285cb7a01acSMauro Carvalho Chehab 286cb7a01acSMauro Carvalho Chehab 0x109, 0x085, /* Luminance control */ 287cb7a01acSMauro Carvalho Chehab 288cb7a01acSMauro Carvalho Chehab /**** from app start ****/ 289cb7a01acSMauro Carvalho Chehab 0x584, 0x000, /* AGC gain control */ 290cb7a01acSMauro Carvalho Chehab 0x585, 0x000, /* Program count */ 291cb7a01acSMauro Carvalho Chehab 0x586, 0x003, /* Status reset */ 292cb7a01acSMauro Carvalho Chehab 0x588, 0x0ff, /* Number of audio samples (L) */ 293cb7a01acSMauro Carvalho Chehab 0x589, 0x00f, /* Number of audio samples (M) */ 294cb7a01acSMauro Carvalho Chehab 0x58a, 0x000, /* Number of audio samples (H) */ 295cb7a01acSMauro Carvalho Chehab 0x58b, 0x000, /* Audio select */ 296cb7a01acSMauro Carvalho Chehab 0x58c, 0x010, /* Audio channel assign1 */ 297cb7a01acSMauro Carvalho Chehab 0x58d, 0x032, /* Audio channel assign2 */ 298cb7a01acSMauro Carvalho Chehab 0x58e, 0x054, /* Audio channel assign3 */ 299cb7a01acSMauro Carvalho Chehab 0x58f, 0x023, /* Audio format */ 300cb7a01acSMauro Carvalho Chehab 0x590, 0x000, /* SIF control */ 301cb7a01acSMauro Carvalho Chehab 302cb7a01acSMauro Carvalho Chehab 0x595, 0x000, /* ?? */ 303cb7a01acSMauro Carvalho Chehab 0x596, 0x000, /* ?? */ 304cb7a01acSMauro Carvalho Chehab 0x597, 0x000, /* ?? */ 305cb7a01acSMauro Carvalho Chehab 306cb7a01acSMauro Carvalho Chehab 0x464, 0x00, /* Digital input crossbar1 */ 307cb7a01acSMauro Carvalho Chehab 308cb7a01acSMauro Carvalho Chehab 0x46c, 0xbbbb10, /* Digital output selection1-3 */ 309cb7a01acSMauro Carvalho Chehab 0x470, 0x101010, /* Digital output selection4-6 */ 310cb7a01acSMauro Carvalho Chehab 311cb7a01acSMauro Carvalho Chehab 0x478, 0x00, /* Sound feature control */ 312cb7a01acSMauro Carvalho Chehab 313cb7a01acSMauro Carvalho Chehab 0x474, 0x18, /* Softmute control */ 314cb7a01acSMauro Carvalho Chehab 315cb7a01acSMauro Carvalho Chehab 0x454, 0x0425b9, /* Sound Easy programming(reset) */ 316cb7a01acSMauro Carvalho Chehab 0x454, 0x042539, /* Sound Easy programming(reset) */ 317cb7a01acSMauro Carvalho Chehab 318cb7a01acSMauro Carvalho Chehab 319cb7a01acSMauro Carvalho Chehab /**** common setting( of DVD play, including scaler commands) ****/ 320cb7a01acSMauro Carvalho Chehab 0x042, 0x003, /* Data path configuration for VBI (TASK A) */ 321cb7a01acSMauro Carvalho Chehab 322cb7a01acSMauro Carvalho Chehab 0x082, 0x003, /* Data path configuration for VBI (TASK B) */ 323cb7a01acSMauro Carvalho Chehab 324cb7a01acSMauro Carvalho Chehab 0x108, 0x0f8, /* Sync control */ 325cb7a01acSMauro Carvalho Chehab 0x2a9, 0x0fd, /* ??? */ 326cb7a01acSMauro Carvalho Chehab 0x102, 0x089, /* select video input "mode 9" */ 327cb7a01acSMauro Carvalho Chehab 0x111, 0x000, /* Mode/delay control */ 328cb7a01acSMauro Carvalho Chehab 329cb7a01acSMauro Carvalho Chehab 0x10e, 0x00a, /* Chroma control 1 */ 330cb7a01acSMauro Carvalho Chehab 331cb7a01acSMauro Carvalho Chehab 0x594, 0x002, /* SIF, analog I/O select */ 332cb7a01acSMauro Carvalho Chehab 333cb7a01acSMauro Carvalho Chehab 0x454, 0x0425b9, /* Sound */ 334cb7a01acSMauro Carvalho Chehab 0x454, 0x042539, 335cb7a01acSMauro Carvalho Chehab 336cb7a01acSMauro Carvalho Chehab 0x111, 0x000, 337cb7a01acSMauro Carvalho Chehab 0x10e, 0x00a, 338cb7a01acSMauro Carvalho Chehab 0x464, 0x000, 339cb7a01acSMauro Carvalho Chehab 0x300, 0x000, 340cb7a01acSMauro Carvalho Chehab 0x301, 0x006, 341cb7a01acSMauro Carvalho Chehab 0x302, 0x000, 342cb7a01acSMauro Carvalho Chehab 0x303, 0x006, 343cb7a01acSMauro Carvalho Chehab 0x308, 0x040, 344cb7a01acSMauro Carvalho Chehab 0x309, 0x000, 345cb7a01acSMauro Carvalho Chehab 0x30a, 0x000, 346cb7a01acSMauro Carvalho Chehab 0x30b, 0x000, 347cb7a01acSMauro Carvalho Chehab 0x000, 0x002, 348cb7a01acSMauro Carvalho Chehab 0x001, 0x000, 349cb7a01acSMauro Carvalho Chehab 0x002, 0x000, 350cb7a01acSMauro Carvalho Chehab 0x003, 0x000, 351cb7a01acSMauro Carvalho Chehab 0x004, 0x033, 352cb7a01acSMauro Carvalho Chehab 0x040, 0x01d, 353cb7a01acSMauro Carvalho Chehab 0x041, 0x001, 354cb7a01acSMauro Carvalho Chehab 0x042, 0x004, 355cb7a01acSMauro Carvalho Chehab 0x043, 0x000, 356cb7a01acSMauro Carvalho Chehab 0x080, 0x01e, 357cb7a01acSMauro Carvalho Chehab 0x081, 0x001, 358cb7a01acSMauro Carvalho Chehab 0x082, 0x004, 359cb7a01acSMauro Carvalho Chehab 0x083, 0x000, 360cb7a01acSMauro Carvalho Chehab 0x190, 0x018, 361cb7a01acSMauro Carvalho Chehab 0x115, 0x000, 362cb7a01acSMauro Carvalho Chehab 0x116, 0x012, 363cb7a01acSMauro Carvalho Chehab 0x117, 0x018, 364cb7a01acSMauro Carvalho Chehab 0x04a, 0x011, 365cb7a01acSMauro Carvalho Chehab 0x08a, 0x011, 366cb7a01acSMauro Carvalho Chehab 0x04b, 0x000, 367cb7a01acSMauro Carvalho Chehab 0x08b, 0x000, 368cb7a01acSMauro Carvalho Chehab 0x048, 0x000, 369cb7a01acSMauro Carvalho Chehab 0x088, 0x000, 370cb7a01acSMauro Carvalho Chehab 0x04e, 0x012, 371cb7a01acSMauro Carvalho Chehab 0x08e, 0x012, 372cb7a01acSMauro Carvalho Chehab 0x058, 0x012, 373cb7a01acSMauro Carvalho Chehab 0x098, 0x012, 374cb7a01acSMauro Carvalho Chehab 0x059, 0x000, 375cb7a01acSMauro Carvalho Chehab 0x099, 0x000, 376cb7a01acSMauro Carvalho Chehab 0x05a, 0x003, 377cb7a01acSMauro Carvalho Chehab 0x09a, 0x003, 378cb7a01acSMauro Carvalho Chehab 0x05b, 0x001, 379cb7a01acSMauro Carvalho Chehab 0x09b, 0x001, 380cb7a01acSMauro Carvalho Chehab 0x054, 0x008, 381cb7a01acSMauro Carvalho Chehab 0x094, 0x008, 382cb7a01acSMauro Carvalho Chehab 0x055, 0x000, 383cb7a01acSMauro Carvalho Chehab 0x095, 0x000, 384cb7a01acSMauro Carvalho Chehab 0x056, 0x0c7, 385cb7a01acSMauro Carvalho Chehab 0x096, 0x0c7, 386cb7a01acSMauro Carvalho Chehab 0x057, 0x002, 387cb7a01acSMauro Carvalho Chehab 0x097, 0x002, 388cb7a01acSMauro Carvalho Chehab 0x0ff, 0x0ff, 389cb7a01acSMauro Carvalho Chehab 0x060, 0x001, 390cb7a01acSMauro Carvalho Chehab 0x0a0, 0x001, 391cb7a01acSMauro Carvalho Chehab 0x061, 0x000, 392cb7a01acSMauro Carvalho Chehab 0x0a1, 0x000, 393cb7a01acSMauro Carvalho Chehab 0x062, 0x000, 394cb7a01acSMauro Carvalho Chehab 0x0a2, 0x000, 395cb7a01acSMauro Carvalho Chehab 0x063, 0x000, 396cb7a01acSMauro Carvalho Chehab 0x0a3, 0x000, 397cb7a01acSMauro Carvalho Chehab 0x070, 0x000, 398cb7a01acSMauro Carvalho Chehab 0x0b0, 0x000, 399cb7a01acSMauro Carvalho Chehab 0x071, 0x004, 400cb7a01acSMauro Carvalho Chehab 0x0b1, 0x004, 401cb7a01acSMauro Carvalho Chehab 0x06c, 0x0e9, 402cb7a01acSMauro Carvalho Chehab 0x0ac, 0x0e9, 403cb7a01acSMauro Carvalho Chehab 0x06d, 0x003, 404cb7a01acSMauro Carvalho Chehab 0x0ad, 0x003, 405cb7a01acSMauro Carvalho Chehab 0x05c, 0x0d0, 406cb7a01acSMauro Carvalho Chehab 0x09c, 0x0d0, 407cb7a01acSMauro Carvalho Chehab 0x05d, 0x002, 408cb7a01acSMauro Carvalho Chehab 0x09d, 0x002, 409cb7a01acSMauro Carvalho Chehab 0x05e, 0x0f2, 410cb7a01acSMauro Carvalho Chehab 0x09e, 0x0f2, 411cb7a01acSMauro Carvalho Chehab 0x05f, 0x000, 412cb7a01acSMauro Carvalho Chehab 0x09f, 0x000, 413cb7a01acSMauro Carvalho Chehab 0x074, 0x000, 414cb7a01acSMauro Carvalho Chehab 0x0b4, 0x000, 415cb7a01acSMauro Carvalho Chehab 0x075, 0x000, 416cb7a01acSMauro Carvalho Chehab 0x0b5, 0x000, 417cb7a01acSMauro Carvalho Chehab 0x076, 0x000, 418cb7a01acSMauro Carvalho Chehab 0x0b6, 0x000, 419cb7a01acSMauro Carvalho Chehab 0x077, 0x000, 420cb7a01acSMauro Carvalho Chehab 0x0b7, 0x000, 421cb7a01acSMauro Carvalho Chehab 0x195, 0x008, 422cb7a01acSMauro Carvalho Chehab 0x0ff, 0x0ff, 423cb7a01acSMauro Carvalho Chehab 0x108, 0x0f8, 424cb7a01acSMauro Carvalho Chehab 0x111, 0x000, 425cb7a01acSMauro Carvalho Chehab 0x10e, 0x00a, 426cb7a01acSMauro Carvalho Chehab 0x2a9, 0x0fd, 427cb7a01acSMauro Carvalho Chehab 0x464, 0x001, 428cb7a01acSMauro Carvalho Chehab 0x454, 0x042135, 429cb7a01acSMauro Carvalho Chehab 0x598, 0x0e7, 430cb7a01acSMauro Carvalho Chehab 0x599, 0x07d, 431cb7a01acSMauro Carvalho Chehab 0x59a, 0x018, 432cb7a01acSMauro Carvalho Chehab 0x59c, 0x066, 433cb7a01acSMauro Carvalho Chehab 0x59d, 0x090, 434cb7a01acSMauro Carvalho Chehab 0x59e, 0x001, 435cb7a01acSMauro Carvalho Chehab 0x584, 0x000, 436cb7a01acSMauro Carvalho Chehab 0x585, 0x000, 437cb7a01acSMauro Carvalho Chehab 0x586, 0x003, 438cb7a01acSMauro Carvalho Chehab 0x588, 0x0ff, 439cb7a01acSMauro Carvalho Chehab 0x589, 0x00f, 440cb7a01acSMauro Carvalho Chehab 0x58a, 0x000, 441cb7a01acSMauro Carvalho Chehab 0x58b, 0x000, 442cb7a01acSMauro Carvalho Chehab 0x58c, 0x010, 443cb7a01acSMauro Carvalho Chehab 0x58d, 0x032, 444cb7a01acSMauro Carvalho Chehab 0x58e, 0x054, 445cb7a01acSMauro Carvalho Chehab 0x58f, 0x023, 446cb7a01acSMauro Carvalho Chehab 0x590, 0x000, 447cb7a01acSMauro Carvalho Chehab 0x595, 0x000, 448cb7a01acSMauro Carvalho Chehab 0x596, 0x000, 449cb7a01acSMauro Carvalho Chehab 0x597, 0x000, 450cb7a01acSMauro Carvalho Chehab 0x464, 0x000, 451cb7a01acSMauro Carvalho Chehab 0x46c, 0xbbbb10, 452cb7a01acSMauro Carvalho Chehab 0x470, 0x101010, 453cb7a01acSMauro Carvalho Chehab 454cb7a01acSMauro Carvalho Chehab 455cb7a01acSMauro Carvalho Chehab 0x478, 0x000, 456cb7a01acSMauro Carvalho Chehab 0x474, 0x018, 457cb7a01acSMauro Carvalho Chehab 0x454, 0x042135, 458cb7a01acSMauro Carvalho Chehab 0x598, 0x0e7, 459cb7a01acSMauro Carvalho Chehab 0x599, 0x07d, 460cb7a01acSMauro Carvalho Chehab 0x59a, 0x018, 461cb7a01acSMauro Carvalho Chehab 0x59c, 0x066, 462cb7a01acSMauro Carvalho Chehab 0x59d, 0x090, 463cb7a01acSMauro Carvalho Chehab 0x59e, 0x001, 464cb7a01acSMauro Carvalho Chehab 0x584, 0x000, 465cb7a01acSMauro Carvalho Chehab 0x585, 0x000, 466cb7a01acSMauro Carvalho Chehab 0x586, 0x003, 467cb7a01acSMauro Carvalho Chehab 0x588, 0x0ff, 468cb7a01acSMauro Carvalho Chehab 0x589, 0x00f, 469cb7a01acSMauro Carvalho Chehab 0x58a, 0x000, 470cb7a01acSMauro Carvalho Chehab 0x58b, 0x000, 471cb7a01acSMauro Carvalho Chehab 0x58c, 0x010, 472cb7a01acSMauro Carvalho Chehab 0x58d, 0x032, 473cb7a01acSMauro Carvalho Chehab 0x58e, 0x054, 474cb7a01acSMauro Carvalho Chehab 0x58f, 0x023, 475cb7a01acSMauro Carvalho Chehab 0x590, 0x000, 476cb7a01acSMauro Carvalho Chehab 0x595, 0x000, 477cb7a01acSMauro Carvalho Chehab 0x596, 0x000, 478cb7a01acSMauro Carvalho Chehab 0x597, 0x000, 479cb7a01acSMauro Carvalho Chehab 0x464, 0x000, 480cb7a01acSMauro Carvalho Chehab 0x46c, 0xbbbb10, 481cb7a01acSMauro Carvalho Chehab 0x470, 0x101010, 482cb7a01acSMauro Carvalho Chehab 483cb7a01acSMauro Carvalho Chehab 0x478, 0x000, 484cb7a01acSMauro Carvalho Chehab 0x474, 0x018, 485cb7a01acSMauro Carvalho Chehab 0x454, 0x042135, 486cb7a01acSMauro Carvalho Chehab 0x598, 0x0e7, 487cb7a01acSMauro Carvalho Chehab 0x599, 0x07d, 488cb7a01acSMauro Carvalho Chehab 0x59a, 0x018, 489cb7a01acSMauro Carvalho Chehab 0x59c, 0x066, 490cb7a01acSMauro Carvalho Chehab 0x59d, 0x090, 491cb7a01acSMauro Carvalho Chehab 0x59e, 0x001, 492cb7a01acSMauro Carvalho Chehab 0x584, 0x000, 493cb7a01acSMauro Carvalho Chehab 0x585, 0x000, 494cb7a01acSMauro Carvalho Chehab 0x586, 0x003, 495cb7a01acSMauro Carvalho Chehab 0x588, 0x0ff, 496cb7a01acSMauro Carvalho Chehab 0x589, 0x00f, 497cb7a01acSMauro Carvalho Chehab 0x58a, 0x000, 498cb7a01acSMauro Carvalho Chehab 0x58b, 0x000, 499cb7a01acSMauro Carvalho Chehab 0x58c, 0x010, 500cb7a01acSMauro Carvalho Chehab 0x58d, 0x032, 501cb7a01acSMauro Carvalho Chehab 0x58e, 0x054, 502cb7a01acSMauro Carvalho Chehab 0x58f, 0x023, 503cb7a01acSMauro Carvalho Chehab 0x590, 0x000, 504cb7a01acSMauro Carvalho Chehab 0x595, 0x000, 505cb7a01acSMauro Carvalho Chehab 0x596, 0x000, 506cb7a01acSMauro Carvalho Chehab 0x597, 0x000, 507cb7a01acSMauro Carvalho Chehab 0x464, 0x000, 508cb7a01acSMauro Carvalho Chehab 0x46c, 0xbbbb10, 509cb7a01acSMauro Carvalho Chehab 0x470, 0x101010, 510cb7a01acSMauro Carvalho Chehab 0x478, 0x000, 511cb7a01acSMauro Carvalho Chehab 0x474, 0x018, 512cb7a01acSMauro Carvalho Chehab 0x454, 0x042135, 513cb7a01acSMauro Carvalho Chehab 0x193, 0x000, 514cb7a01acSMauro Carvalho Chehab 0x300, 0x000, 515cb7a01acSMauro Carvalho Chehab 0x301, 0x006, 516cb7a01acSMauro Carvalho Chehab 0x302, 0x000, 517cb7a01acSMauro Carvalho Chehab 0x303, 0x006, 518cb7a01acSMauro Carvalho Chehab 0x308, 0x040, 519cb7a01acSMauro Carvalho Chehab 0x309, 0x000, 520cb7a01acSMauro Carvalho Chehab 0x30a, 0x000, 521cb7a01acSMauro Carvalho Chehab 0x30b, 0x000, 522cb7a01acSMauro Carvalho Chehab 0x000, 0x002, 523cb7a01acSMauro Carvalho Chehab 0x001, 0x000, 524cb7a01acSMauro Carvalho Chehab 0x002, 0x000, 525cb7a01acSMauro Carvalho Chehab 0x003, 0x000, 526cb7a01acSMauro Carvalho Chehab 0x004, 0x033, 527cb7a01acSMauro Carvalho Chehab 0x040, 0x01d, 528cb7a01acSMauro Carvalho Chehab 0x041, 0x001, 529cb7a01acSMauro Carvalho Chehab 0x042, 0x004, 530cb7a01acSMauro Carvalho Chehab 0x043, 0x000, 531cb7a01acSMauro Carvalho Chehab 0x080, 0x01e, 532cb7a01acSMauro Carvalho Chehab 0x081, 0x001, 533cb7a01acSMauro Carvalho Chehab 0x082, 0x004, 534cb7a01acSMauro Carvalho Chehab 0x083, 0x000, 535cb7a01acSMauro Carvalho Chehab 0x190, 0x018, 536cb7a01acSMauro Carvalho Chehab 0x115, 0x000, 537cb7a01acSMauro Carvalho Chehab 0x116, 0x012, 538cb7a01acSMauro Carvalho Chehab 0x117, 0x018, 539cb7a01acSMauro Carvalho Chehab 0x04a, 0x011, 540cb7a01acSMauro Carvalho Chehab 0x08a, 0x011, 541cb7a01acSMauro Carvalho Chehab 0x04b, 0x000, 542cb7a01acSMauro Carvalho Chehab 0x08b, 0x000, 543cb7a01acSMauro Carvalho Chehab 0x048, 0x000, 544cb7a01acSMauro Carvalho Chehab 0x088, 0x000, 545cb7a01acSMauro Carvalho Chehab 0x04e, 0x012, 546cb7a01acSMauro Carvalho Chehab 0x08e, 0x012, 547cb7a01acSMauro Carvalho Chehab 0x058, 0x012, 548cb7a01acSMauro Carvalho Chehab 0x098, 0x012, 549cb7a01acSMauro Carvalho Chehab 0x059, 0x000, 550cb7a01acSMauro Carvalho Chehab 0x099, 0x000, 551cb7a01acSMauro Carvalho Chehab 0x05a, 0x003, 552cb7a01acSMauro Carvalho Chehab 0x09a, 0x003, 553cb7a01acSMauro Carvalho Chehab 0x05b, 0x001, 554cb7a01acSMauro Carvalho Chehab 0x09b, 0x001, 555cb7a01acSMauro Carvalho Chehab 0x054, 0x008, 556cb7a01acSMauro Carvalho Chehab 0x094, 0x008, 557cb7a01acSMauro Carvalho Chehab 0x055, 0x000, 558cb7a01acSMauro Carvalho Chehab 0x095, 0x000, 559cb7a01acSMauro Carvalho Chehab 0x056, 0x0c7, 560cb7a01acSMauro Carvalho Chehab 0x096, 0x0c7, 561cb7a01acSMauro Carvalho Chehab 0x057, 0x002, 562cb7a01acSMauro Carvalho Chehab 0x097, 0x002, 563cb7a01acSMauro Carvalho Chehab 0x060, 0x001, 564cb7a01acSMauro Carvalho Chehab 0x0a0, 0x001, 565cb7a01acSMauro Carvalho Chehab 0x061, 0x000, 566cb7a01acSMauro Carvalho Chehab 0x0a1, 0x000, 567cb7a01acSMauro Carvalho Chehab 0x062, 0x000, 568cb7a01acSMauro Carvalho Chehab 0x0a2, 0x000, 569cb7a01acSMauro Carvalho Chehab 0x063, 0x000, 570cb7a01acSMauro Carvalho Chehab 0x0a3, 0x000, 571cb7a01acSMauro Carvalho Chehab 0x070, 0x000, 572cb7a01acSMauro Carvalho Chehab 0x0b0, 0x000, 573cb7a01acSMauro Carvalho Chehab 0x071, 0x004, 574cb7a01acSMauro Carvalho Chehab 0x0b1, 0x004, 575cb7a01acSMauro Carvalho Chehab 0x06c, 0x0e9, 576cb7a01acSMauro Carvalho Chehab 0x0ac, 0x0e9, 577cb7a01acSMauro Carvalho Chehab 0x06d, 0x003, 578cb7a01acSMauro Carvalho Chehab 0x0ad, 0x003, 579cb7a01acSMauro Carvalho Chehab 0x05c, 0x0d0, 580cb7a01acSMauro Carvalho Chehab 0x09c, 0x0d0, 581cb7a01acSMauro Carvalho Chehab 0x05d, 0x002, 582cb7a01acSMauro Carvalho Chehab 0x09d, 0x002, 583cb7a01acSMauro Carvalho Chehab 0x05e, 0x0f2, 584cb7a01acSMauro Carvalho Chehab 0x09e, 0x0f2, 585cb7a01acSMauro Carvalho Chehab 0x05f, 0x000, 586cb7a01acSMauro Carvalho Chehab 0x09f, 0x000, 587cb7a01acSMauro Carvalho Chehab 0x074, 0x000, 588cb7a01acSMauro Carvalho Chehab 0x0b4, 0x000, 589cb7a01acSMauro Carvalho Chehab 0x075, 0x000, 590cb7a01acSMauro Carvalho Chehab 0x0b5, 0x000, 591cb7a01acSMauro Carvalho Chehab 0x076, 0x000, 592cb7a01acSMauro Carvalho Chehab 0x0b6, 0x000, 593cb7a01acSMauro Carvalho Chehab 0x077, 0x000, 594cb7a01acSMauro Carvalho Chehab 0x0b7, 0x000, 595cb7a01acSMauro Carvalho Chehab 0x195, 0x008, 596cb7a01acSMauro Carvalho Chehab 0x598, 0x0e7, 597cb7a01acSMauro Carvalho Chehab 0x599, 0x07d, 598cb7a01acSMauro Carvalho Chehab 0x59a, 0x018, 599cb7a01acSMauro Carvalho Chehab 0x59c, 0x066, 600cb7a01acSMauro Carvalho Chehab 0x59d, 0x090, 601cb7a01acSMauro Carvalho Chehab 0x59e, 0x001, 602cb7a01acSMauro Carvalho Chehab 0x584, 0x000, 603cb7a01acSMauro Carvalho Chehab 0x585, 0x000, 604cb7a01acSMauro Carvalho Chehab 0x586, 0x003, 605cb7a01acSMauro Carvalho Chehab 0x588, 0x0ff, 606cb7a01acSMauro Carvalho Chehab 0x589, 0x00f, 607cb7a01acSMauro Carvalho Chehab 0x58a, 0x000, 608cb7a01acSMauro Carvalho Chehab 0x58b, 0x000, 609cb7a01acSMauro Carvalho Chehab 0x58c, 0x010, 610cb7a01acSMauro Carvalho Chehab 0x58d, 0x032, 611cb7a01acSMauro Carvalho Chehab 0x58e, 0x054, 612cb7a01acSMauro Carvalho Chehab 0x58f, 0x023, 613cb7a01acSMauro Carvalho Chehab 0x590, 0x000, 614cb7a01acSMauro Carvalho Chehab 0x595, 0x000, 615cb7a01acSMauro Carvalho Chehab 0x596, 0x000, 616cb7a01acSMauro Carvalho Chehab 0x597, 0x000, 617cb7a01acSMauro Carvalho Chehab 0x464, 0x000, 618cb7a01acSMauro Carvalho Chehab 0x46c, 0xbbbb10, 619cb7a01acSMauro Carvalho Chehab 0x470, 0x101010, 620cb7a01acSMauro Carvalho Chehab 0x478, 0x000, 621cb7a01acSMauro Carvalho Chehab 0x474, 0x018, 622cb7a01acSMauro Carvalho Chehab 0x454, 0x042135, 623cb7a01acSMauro Carvalho Chehab 0x193, 0x0a6, 624cb7a01acSMauro Carvalho Chehab 0x108, 0x0f8, 625cb7a01acSMauro Carvalho Chehab 0x042, 0x003, 626cb7a01acSMauro Carvalho Chehab 0x082, 0x003, 627cb7a01acSMauro Carvalho Chehab 0x454, 0x0425b9, 628cb7a01acSMauro Carvalho Chehab 0x454, 0x042539, 629cb7a01acSMauro Carvalho Chehab 0x193, 0x000, 630cb7a01acSMauro Carvalho Chehab 0x193, 0x0a6, 631cb7a01acSMauro Carvalho Chehab 0x464, 0x000, 632cb7a01acSMauro Carvalho Chehab 633cb7a01acSMauro Carvalho Chehab 0, 0 634cb7a01acSMauro Carvalho Chehab }; 635cb7a01acSMauro Carvalho Chehab 636cb7a01acSMauro Carvalho Chehab /* Tuner */ 637cb7a01acSMauro Carvalho Chehab static u32 reg_init_tuner_input[] = { 638cb7a01acSMauro Carvalho Chehab 0x108, 0x0f8, /* Sync control */ 639cb7a01acSMauro Carvalho Chehab 0x111, 0x000, /* Mode/delay control */ 640cb7a01acSMauro Carvalho Chehab 0x10e, 0x00a, /* Chroma control 1 */ 641cb7a01acSMauro Carvalho Chehab 0, 0 642cb7a01acSMauro Carvalho Chehab }; 643cb7a01acSMauro Carvalho Chehab 644cb7a01acSMauro Carvalho Chehab /* Composite */ 645cb7a01acSMauro Carvalho Chehab static u32 reg_init_composite_input[] = { 646cb7a01acSMauro Carvalho Chehab 0x108, 0x0e8, /* Sync control */ 647cb7a01acSMauro Carvalho Chehab 0x111, 0x000, /* Mode/delay control */ 648cb7a01acSMauro Carvalho Chehab 0x10e, 0x04a, /* Chroma control 1 */ 649cb7a01acSMauro Carvalho Chehab 0, 0 650cb7a01acSMauro Carvalho Chehab }; 651cb7a01acSMauro Carvalho Chehab 652cb7a01acSMauro Carvalho Chehab /* S-Video */ 653cb7a01acSMauro Carvalho Chehab static u32 reg_init_svideo_input[] = { 654cb7a01acSMauro Carvalho Chehab 0x108, 0x0e8, /* Sync control */ 655cb7a01acSMauro Carvalho Chehab 0x111, 0x000, /* Mode/delay control */ 656cb7a01acSMauro Carvalho Chehab 0x10e, 0x04a, /* Chroma control 1 */ 657cb7a01acSMauro Carvalho Chehab 0, 0 658cb7a01acSMauro Carvalho Chehab }; 659cb7a01acSMauro Carvalho Chehab 660cb7a01acSMauro Carvalho Chehab static u32 reg_set_audio_template[4][2] = 661cb7a01acSMauro Carvalho Chehab { 662cb7a01acSMauro Carvalho Chehab { /* for MONO 663cb7a01acSMauro Carvalho Chehab tadachi 6/29 DMA audio output select? 664cb7a01acSMauro Carvalho Chehab Register 0x46c 665cb7a01acSMauro Carvalho Chehab 7-4: DMA2, 3-0: DMA1 ch. DMA4, DMA3 DMA2, DMA1 666cb7a01acSMauro Carvalho Chehab 0: MAIN left, 1: MAIN right 667cb7a01acSMauro Carvalho Chehab 2: AUX1 left, 3: AUX1 right 668cb7a01acSMauro Carvalho Chehab 4: AUX2 left, 5: AUX2 right 669cb7a01acSMauro Carvalho Chehab 6: DPL left, 7: DPL right 670cb7a01acSMauro Carvalho Chehab 8: DPL center, 9: DPL surround 671cb7a01acSMauro Carvalho Chehab A: monitor output, B: digital sense */ 672cb7a01acSMauro Carvalho Chehab 0xbbbb00, 673cb7a01acSMauro Carvalho Chehab 674cb7a01acSMauro Carvalho Chehab /* tadachi 6/29 DAC and I2S output select? 675cb7a01acSMauro Carvalho Chehab Register 0x470 676cb7a01acSMauro Carvalho Chehab 7-4:DAC right ch. 3-0:DAC left ch. 677cb7a01acSMauro Carvalho Chehab I2S1 right,left I2S2 right,left */ 678cb7a01acSMauro Carvalho Chehab 0x00, 679cb7a01acSMauro Carvalho Chehab }, 680cb7a01acSMauro Carvalho Chehab { /* for STEREO */ 681cb7a01acSMauro Carvalho Chehab 0xbbbb10, 0x101010, 682cb7a01acSMauro Carvalho Chehab }, 683cb7a01acSMauro Carvalho Chehab { /* for LANG1 */ 684cb7a01acSMauro Carvalho Chehab 0xbbbb00, 0x00, 685cb7a01acSMauro Carvalho Chehab }, 686cb7a01acSMauro Carvalho Chehab { /* for LANG2/SAP */ 687cb7a01acSMauro Carvalho Chehab 0xbbbb11, 0x111111, 688cb7a01acSMauro Carvalho Chehab } 689cb7a01acSMauro Carvalho Chehab }; 690cb7a01acSMauro Carvalho Chehab 691cb7a01acSMauro Carvalho Chehab 692cb7a01acSMauro Carvalho Chehab /* Get detected audio flags (from saa7134 driver) */ 693cb7a01acSMauro Carvalho Chehab static void get_inf_dev_status(struct v4l2_subdev *sd, 694cb7a01acSMauro Carvalho Chehab int *dual_flag, int *stereo_flag) 695cb7a01acSMauro Carvalho Chehab { 696cb7a01acSMauro Carvalho Chehab u32 reg_data3; 697cb7a01acSMauro Carvalho Chehab 698cb7a01acSMauro Carvalho Chehab static char *stdres[0x20] = { 699cb7a01acSMauro Carvalho Chehab [0x00] = "no standard detected", 700cb7a01acSMauro Carvalho Chehab [0x01] = "B/G (in progress)", 701cb7a01acSMauro Carvalho Chehab [0x02] = "D/K (in progress)", 702cb7a01acSMauro Carvalho Chehab [0x03] = "M (in progress)", 703cb7a01acSMauro Carvalho Chehab 704cb7a01acSMauro Carvalho Chehab [0x04] = "B/G A2", 705cb7a01acSMauro Carvalho Chehab [0x05] = "B/G NICAM", 706cb7a01acSMauro Carvalho Chehab [0x06] = "D/K A2 (1)", 707cb7a01acSMauro Carvalho Chehab [0x07] = "D/K A2 (2)", 708cb7a01acSMauro Carvalho Chehab [0x08] = "D/K A2 (3)", 709cb7a01acSMauro Carvalho Chehab [0x09] = "D/K NICAM", 710cb7a01acSMauro Carvalho Chehab [0x0a] = "L NICAM", 711cb7a01acSMauro Carvalho Chehab [0x0b] = "I NICAM", 712cb7a01acSMauro Carvalho Chehab 713cb7a01acSMauro Carvalho Chehab [0x0c] = "M Korea", 714cb7a01acSMauro Carvalho Chehab [0x0d] = "M BTSC ", 715cb7a01acSMauro Carvalho Chehab [0x0e] = "M EIAJ", 716cb7a01acSMauro Carvalho Chehab 717cb7a01acSMauro Carvalho Chehab [0x0f] = "FM radio / IF 10.7 / 50 deemp", 718cb7a01acSMauro Carvalho Chehab [0x10] = "FM radio / IF 10.7 / 75 deemp", 719cb7a01acSMauro Carvalho Chehab [0x11] = "FM radio / IF sel / 50 deemp", 720cb7a01acSMauro Carvalho Chehab [0x12] = "FM radio / IF sel / 75 deemp", 721cb7a01acSMauro Carvalho Chehab 722cb7a01acSMauro Carvalho Chehab [0x13 ... 0x1e] = "unknown", 723cb7a01acSMauro Carvalho Chehab [0x1f] = "??? [in progress]", 724cb7a01acSMauro Carvalho Chehab }; 725cb7a01acSMauro Carvalho Chehab 726cb7a01acSMauro Carvalho Chehab 727cb7a01acSMauro Carvalho Chehab *dual_flag = *stereo_flag = 0; 728cb7a01acSMauro Carvalho Chehab 729cb7a01acSMauro Carvalho Chehab /* (demdec status: 0x528) */ 730cb7a01acSMauro Carvalho Chehab 731cb7a01acSMauro Carvalho Chehab /* read current status */ 732cb7a01acSMauro Carvalho Chehab reg_data3 = saa717x_read(sd, 0x0528); 733cb7a01acSMauro Carvalho Chehab 734cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n", 735cb7a01acSMauro Carvalho Chehab reg_data3, stdres[reg_data3 & 0x1f], 736cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000020) ? ",stereo" : "", 737cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000040) ? ",dual" : ""); 738cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "detailed status: " 739cb7a01acSMauro Carvalho Chehab "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", 740cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "", 741cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "", 742cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000200) ? " A2/EIAJ stereo " : "", 743cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000400) ? " A2/EIAJ noise mute " : "", 744cb7a01acSMauro Carvalho Chehab 745cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x000800) ? " BTSC/FM radio pilot " : "", 746cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x001000) ? " SAP carrier " : "", 747cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x002000) ? " BTSC stereo noise mute " : "", 748cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x004000) ? " SAP noise mute " : "", 749cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x008000) ? " VDSP " : "", 750cb7a01acSMauro Carvalho Chehab 751cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x010000) ? " NICST " : "", 752cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x020000) ? " NICDU " : "", 753cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x040000) ? " NICAM muted " : "", 754cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x080000) ? " NICAM reserve sound " : "", 755cb7a01acSMauro Carvalho Chehab 756cb7a01acSMauro Carvalho Chehab (reg_data3 & 0x100000) ? " init done " : ""); 757cb7a01acSMauro Carvalho Chehab 758cb7a01acSMauro Carvalho Chehab if (reg_data3 & 0x000220) { 759cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "ST!!!\n"); 760cb7a01acSMauro Carvalho Chehab *stereo_flag = 1; 761cb7a01acSMauro Carvalho Chehab } 762cb7a01acSMauro Carvalho Chehab 763cb7a01acSMauro Carvalho Chehab if (reg_data3 & 0x000140) { 764cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DUAL!!!\n"); 765cb7a01acSMauro Carvalho Chehab *dual_flag = 1; 766cb7a01acSMauro Carvalho Chehab } 767cb7a01acSMauro Carvalho Chehab } 768cb7a01acSMauro Carvalho Chehab 769cb7a01acSMauro Carvalho Chehab /* regs write to set audio mode */ 770cb7a01acSMauro Carvalho Chehab static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode) 771cb7a01acSMauro Carvalho Chehab { 772cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n", 773cb7a01acSMauro Carvalho Chehab audio_mode); 774cb7a01acSMauro Carvalho Chehab 775cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]); 776cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]); 777cb7a01acSMauro Carvalho Chehab } 778cb7a01acSMauro Carvalho Chehab 779cb7a01acSMauro Carvalho Chehab /* write regs to set audio volume, bass and treble */ 780cb7a01acSMauro Carvalho Chehab static int set_audio_regs(struct v4l2_subdev *sd, 781cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder) 782cb7a01acSMauro Carvalho Chehab { 783cb7a01acSMauro Carvalho Chehab u8 mute = 0xac; /* -84 dB */ 784cb7a01acSMauro Carvalho Chehab u32 val; 785cb7a01acSMauro Carvalho Chehab unsigned int work_l, work_r; 786cb7a01acSMauro Carvalho Chehab 787cb7a01acSMauro Carvalho Chehab /* set SIF analog I/O select */ 788cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x0594, decoder->audio_input); 789cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "set audio input %d\n", 790cb7a01acSMauro Carvalho Chehab decoder->audio_input); 791cb7a01acSMauro Carvalho Chehab 792cb7a01acSMauro Carvalho Chehab /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */ 793cb7a01acSMauro Carvalho Chehab work_l = (min(65536 - decoder->audio_main_balance, 32768) * decoder->audio_main_volume) / 32768; 794cb7a01acSMauro Carvalho Chehab work_r = (min(decoder->audio_main_balance, (u16)32768) * decoder->audio_main_volume) / 32768; 795cb7a01acSMauro Carvalho Chehab decoder->audio_main_vol_l = (long)work_l * (24 - (-40)) / 65535 - 40; 796cb7a01acSMauro Carvalho Chehab decoder->audio_main_vol_r = (long)work_r * (24 - (-40)) / 65535 - 40; 797cb7a01acSMauro Carvalho Chehab 798cb7a01acSMauro Carvalho Chehab /* set main volume */ 799cb7a01acSMauro Carvalho Chehab /* main volume L[7-0],R[7-0],0x00 24=24dB,-83dB, -84(mute) */ 800cb7a01acSMauro Carvalho Chehab /* def:0dB->6dB(MPG600GR) */ 801cb7a01acSMauro Carvalho Chehab /* if mute is on, set mute */ 802cb7a01acSMauro Carvalho Chehab if (decoder->audio_main_mute) { 803cb7a01acSMauro Carvalho Chehab val = mute | (mute << 8); 804cb7a01acSMauro Carvalho Chehab } else { 805cb7a01acSMauro Carvalho Chehab val = (u8)decoder->audio_main_vol_l | 806cb7a01acSMauro Carvalho Chehab ((u8)decoder->audio_main_vol_r << 8); 807cb7a01acSMauro Carvalho Chehab } 808cb7a01acSMauro Carvalho Chehab 809cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x480, val); 810cb7a01acSMauro Carvalho Chehab 811cb7a01acSMauro Carvalho Chehab /* set bass and treble */ 812cb7a01acSMauro Carvalho Chehab val = decoder->audio_main_bass & 0x1f; 813cb7a01acSMauro Carvalho Chehab val |= (decoder->audio_main_treble & 0x1f) << 5; 814cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x488, val); 815cb7a01acSMauro Carvalho Chehab return 0; 816cb7a01acSMauro Carvalho Chehab } 817cb7a01acSMauro Carvalho Chehab 818cb7a01acSMauro Carvalho Chehab /********** scaling staff ***********/ 819cb7a01acSMauro Carvalho Chehab static void set_h_prescale(struct v4l2_subdev *sd, 820cb7a01acSMauro Carvalho Chehab int task, int prescale) 821cb7a01acSMauro Carvalho Chehab { 822cb7a01acSMauro Carvalho Chehab static const struct { 823cb7a01acSMauro Carvalho Chehab int xpsc; 824cb7a01acSMauro Carvalho Chehab int xacl; 825cb7a01acSMauro Carvalho Chehab int xc2_1; 826cb7a01acSMauro Carvalho Chehab int xdcg; 827cb7a01acSMauro Carvalho Chehab int vpfy; 828cb7a01acSMauro Carvalho Chehab } vals[] = { 829cb7a01acSMauro Carvalho Chehab /* XPSC XACL XC2_1 XDCG VPFY */ 830cb7a01acSMauro Carvalho Chehab { 1, 0, 0, 0, 0 }, 831cb7a01acSMauro Carvalho Chehab { 2, 2, 1, 2, 2 }, 832cb7a01acSMauro Carvalho Chehab { 3, 4, 1, 3, 2 }, 833cb7a01acSMauro Carvalho Chehab { 4, 8, 1, 4, 2 }, 834cb7a01acSMauro Carvalho Chehab { 5, 8, 1, 4, 2 }, 835cb7a01acSMauro Carvalho Chehab { 6, 8, 1, 4, 3 }, 836cb7a01acSMauro Carvalho Chehab { 7, 8, 1, 4, 3 }, 837cb7a01acSMauro Carvalho Chehab { 8, 15, 0, 4, 3 }, 838cb7a01acSMauro Carvalho Chehab { 9, 15, 0, 4, 3 }, 839cb7a01acSMauro Carvalho Chehab { 10, 16, 1, 5, 3 }, 840cb7a01acSMauro Carvalho Chehab }; 841cb7a01acSMauro Carvalho Chehab static const int count = ARRAY_SIZE(vals); 842cb7a01acSMauro Carvalho Chehab int i, task_shift; 843cb7a01acSMauro Carvalho Chehab 844cb7a01acSMauro Carvalho Chehab task_shift = task * 0x40; 845cb7a01acSMauro Carvalho Chehab for (i = 0; i < count; i++) 846cb7a01acSMauro Carvalho Chehab if (vals[i].xpsc == prescale) 847cb7a01acSMauro Carvalho Chehab break; 848cb7a01acSMauro Carvalho Chehab if (i == count) 849cb7a01acSMauro Carvalho Chehab return; 850cb7a01acSMauro Carvalho Chehab 851cb7a01acSMauro Carvalho Chehab /* horizonal prescaling */ 852cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc); 853cb7a01acSMauro Carvalho Chehab /* accumulation length */ 854cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x61 + task_shift, vals[i].xacl); 855cb7a01acSMauro Carvalho Chehab /* level control */ 856cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x62 + task_shift, 857cb7a01acSMauro Carvalho Chehab (vals[i].xc2_1 << 3) | vals[i].xdcg); 858cb7a01acSMauro Carvalho Chehab /*FIR prefilter control */ 859cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x63 + task_shift, 860cb7a01acSMauro Carvalho Chehab (vals[i].vpfy << 2) | vals[i].vpfy); 861cb7a01acSMauro Carvalho Chehab } 862cb7a01acSMauro Carvalho Chehab 863cb7a01acSMauro Carvalho Chehab /********** scaling staff ***********/ 864cb7a01acSMauro Carvalho Chehab static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale) 865cb7a01acSMauro Carvalho Chehab { 866cb7a01acSMauro Carvalho Chehab int task_shift; 867cb7a01acSMauro Carvalho Chehab 868cb7a01acSMauro Carvalho Chehab task_shift = task * 0x40; 869cb7a01acSMauro Carvalho Chehab /* Vertical scaling ratio (LOW) */ 870cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x70 + task_shift, yscale & 0xff); 871cb7a01acSMauro Carvalho Chehab /* Vertical scaling ratio (HI) */ 872cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x71 + task_shift, yscale >> 8); 873cb7a01acSMauro Carvalho Chehab } 874cb7a01acSMauro Carvalho Chehab 875cb7a01acSMauro Carvalho Chehab static int saa717x_s_ctrl(struct v4l2_ctrl *ctrl) 876cb7a01acSMauro Carvalho Chehab { 877cb7a01acSMauro Carvalho Chehab struct v4l2_subdev *sd = to_sd(ctrl); 878cb7a01acSMauro Carvalho Chehab struct saa717x_state *state = to_state(sd); 879cb7a01acSMauro Carvalho Chehab 880cb7a01acSMauro Carvalho Chehab switch (ctrl->id) { 881cb7a01acSMauro Carvalho Chehab case V4L2_CID_BRIGHTNESS: 882cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x10a, ctrl->val); 883cb7a01acSMauro Carvalho Chehab return 0; 884cb7a01acSMauro Carvalho Chehab 885cb7a01acSMauro Carvalho Chehab case V4L2_CID_CONTRAST: 886cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x10b, ctrl->val); 887cb7a01acSMauro Carvalho Chehab return 0; 888cb7a01acSMauro Carvalho Chehab 889cb7a01acSMauro Carvalho Chehab case V4L2_CID_SATURATION: 890cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x10c, ctrl->val); 891cb7a01acSMauro Carvalho Chehab return 0; 892cb7a01acSMauro Carvalho Chehab 893cb7a01acSMauro Carvalho Chehab case V4L2_CID_HUE: 894cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x10d, ctrl->val); 895cb7a01acSMauro Carvalho Chehab return 0; 896cb7a01acSMauro Carvalho Chehab 897cb7a01acSMauro Carvalho Chehab case V4L2_CID_AUDIO_MUTE: 898cb7a01acSMauro Carvalho Chehab state->audio_main_mute = ctrl->val; 899cb7a01acSMauro Carvalho Chehab break; 900cb7a01acSMauro Carvalho Chehab 901cb7a01acSMauro Carvalho Chehab case V4L2_CID_AUDIO_VOLUME: 902cb7a01acSMauro Carvalho Chehab state->audio_main_volume = ctrl->val; 903cb7a01acSMauro Carvalho Chehab break; 904cb7a01acSMauro Carvalho Chehab 905cb7a01acSMauro Carvalho Chehab case V4L2_CID_AUDIO_BALANCE: 906cb7a01acSMauro Carvalho Chehab state->audio_main_balance = ctrl->val; 907cb7a01acSMauro Carvalho Chehab break; 908cb7a01acSMauro Carvalho Chehab 909cb7a01acSMauro Carvalho Chehab case V4L2_CID_AUDIO_TREBLE: 910cb7a01acSMauro Carvalho Chehab state->audio_main_treble = ctrl->val; 911cb7a01acSMauro Carvalho Chehab break; 912cb7a01acSMauro Carvalho Chehab 913cb7a01acSMauro Carvalho Chehab case V4L2_CID_AUDIO_BASS: 914cb7a01acSMauro Carvalho Chehab state->audio_main_bass = ctrl->val; 915cb7a01acSMauro Carvalho Chehab break; 916cb7a01acSMauro Carvalho Chehab 917cb7a01acSMauro Carvalho Chehab default: 918cb7a01acSMauro Carvalho Chehab return 0; 919cb7a01acSMauro Carvalho Chehab } 920cb7a01acSMauro Carvalho Chehab set_audio_regs(sd, state); 921cb7a01acSMauro Carvalho Chehab return 0; 922cb7a01acSMauro Carvalho Chehab } 923cb7a01acSMauro Carvalho Chehab 924cb7a01acSMauro Carvalho Chehab static int saa717x_s_video_routing(struct v4l2_subdev *sd, 925cb7a01acSMauro Carvalho Chehab u32 input, u32 output, u32 config) 926cb7a01acSMauro Carvalho Chehab { 927cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 928cb7a01acSMauro Carvalho Chehab int is_tuner = input & 0x80; /* tuner input flag */ 929cb7a01acSMauro Carvalho Chehab 930cb7a01acSMauro Carvalho Chehab input &= 0x7f; 931cb7a01acSMauro Carvalho Chehab 932cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", input); 933cb7a01acSMauro Carvalho Chehab /* inputs from 0-9 are available*/ 934cb7a01acSMauro Carvalho Chehab /* saa717x have mode0-mode9 but mode5 is reserved. */ 935cb7a01acSMauro Carvalho Chehab if (input > 9 || input == 5) 936cb7a01acSMauro Carvalho Chehab return -EINVAL; 937cb7a01acSMauro Carvalho Chehab 938cb7a01acSMauro Carvalho Chehab if (decoder->input != input) { 939cb7a01acSMauro Carvalho Chehab int input_line = input; 940cb7a01acSMauro Carvalho Chehab 941cb7a01acSMauro Carvalho Chehab decoder->input = input_line; 942cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "now setting %s input %d\n", 943cb7a01acSMauro Carvalho Chehab input_line >= 6 ? "S-Video" : "Composite", 944cb7a01acSMauro Carvalho Chehab input_line); 945cb7a01acSMauro Carvalho Chehab 946cb7a01acSMauro Carvalho Chehab /* select mode */ 947cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x102, 948cb7a01acSMauro Carvalho Chehab (saa717x_read(sd, 0x102) & 0xf0) | 949cb7a01acSMauro Carvalho Chehab input_line); 950cb7a01acSMauro Carvalho Chehab 951cb7a01acSMauro Carvalho Chehab /* bypass chrominance trap for modes 6..9 */ 952cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x109, 953cb7a01acSMauro Carvalho Chehab (saa717x_read(sd, 0x109) & 0x7f) | 954cb7a01acSMauro Carvalho Chehab (input_line < 6 ? 0x0 : 0x80)); 955cb7a01acSMauro Carvalho Chehab 956cb7a01acSMauro Carvalho Chehab /* change audio_mode */ 957cb7a01acSMauro Carvalho Chehab if (is_tuner) { 958cb7a01acSMauro Carvalho Chehab /* tuner */ 959cb7a01acSMauro Carvalho Chehab set_audio_mode(sd, decoder->tuner_audio_mode); 960cb7a01acSMauro Carvalho Chehab } else { 961cb7a01acSMauro Carvalho Chehab /* Force to STEREO mode if Composite or 962cb7a01acSMauro Carvalho Chehab * S-Video were chosen */ 963cb7a01acSMauro Carvalho Chehab set_audio_mode(sd, TUNER_AUDIO_STEREO); 964cb7a01acSMauro Carvalho Chehab } 965cb7a01acSMauro Carvalho Chehab /* change initialize procedure (Composite/S-Video) */ 966cb7a01acSMauro Carvalho Chehab if (is_tuner) 967cb7a01acSMauro Carvalho Chehab saa717x_write_regs(sd, reg_init_tuner_input); 968cb7a01acSMauro Carvalho Chehab else if (input_line >= 6) 969cb7a01acSMauro Carvalho Chehab saa717x_write_regs(sd, reg_init_svideo_input); 970cb7a01acSMauro Carvalho Chehab else 971cb7a01acSMauro Carvalho Chehab saa717x_write_regs(sd, reg_init_composite_input); 972cb7a01acSMauro Carvalho Chehab } 973cb7a01acSMauro Carvalho Chehab 974cb7a01acSMauro Carvalho Chehab return 0; 975cb7a01acSMauro Carvalho Chehab } 976cb7a01acSMauro Carvalho Chehab 977cb7a01acSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 978cb7a01acSMauro Carvalho Chehab static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 979cb7a01acSMauro Carvalho Chehab { 980cb7a01acSMauro Carvalho Chehab reg->val = saa717x_read(sd, reg->reg); 981cb7a01acSMauro Carvalho Chehab reg->size = 1; 982cb7a01acSMauro Carvalho Chehab return 0; 983cb7a01acSMauro Carvalho Chehab } 984cb7a01acSMauro Carvalho Chehab 985977ba3b1SHans Verkuil static int saa717x_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg) 986cb7a01acSMauro Carvalho Chehab { 987cb7a01acSMauro Carvalho Chehab u16 addr = reg->reg & 0xffff; 988cb7a01acSMauro Carvalho Chehab u8 val = reg->val & 0xff; 989cb7a01acSMauro Carvalho Chehab 990cb7a01acSMauro Carvalho Chehab saa717x_write(sd, addr, val); 991cb7a01acSMauro Carvalho Chehab return 0; 992cb7a01acSMauro Carvalho Chehab } 993cb7a01acSMauro Carvalho Chehab #endif 994cb7a01acSMauro Carvalho Chehab 9956e80c473SHans Verkuil static int saa717x_set_fmt(struct v4l2_subdev *sd, 9966e80c473SHans Verkuil struct v4l2_subdev_pad_config *cfg, 9976e80c473SHans Verkuil struct v4l2_subdev_format *format) 998cb7a01acSMauro Carvalho Chehab { 9996e80c473SHans Verkuil struct v4l2_mbus_framefmt *fmt = &format->format; 1000cb7a01acSMauro Carvalho Chehab int prescale, h_scale, v_scale; 1001cb7a01acSMauro Carvalho Chehab 1002cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "decoder set size\n"); 1003cb7a01acSMauro Carvalho Chehab 10046e80c473SHans Verkuil if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED) 1005cb7a01acSMauro Carvalho Chehab return -EINVAL; 1006cb7a01acSMauro Carvalho Chehab 1007cb7a01acSMauro Carvalho Chehab /* FIXME need better bounds checking here */ 1008cb7a01acSMauro Carvalho Chehab if (fmt->width < 1 || fmt->width > 1440) 1009cb7a01acSMauro Carvalho Chehab return -EINVAL; 1010cb7a01acSMauro Carvalho Chehab if (fmt->height < 1 || fmt->height > 960) 1011cb7a01acSMauro Carvalho Chehab return -EINVAL; 1012cb7a01acSMauro Carvalho Chehab 1013cb7a01acSMauro Carvalho Chehab fmt->field = V4L2_FIELD_INTERLACED; 1014cb7a01acSMauro Carvalho Chehab fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 1015cb7a01acSMauro Carvalho Chehab 10166e80c473SHans Verkuil if (format->which == V4L2_SUBDEV_FORMAT_TRY) 10176e80c473SHans Verkuil return 0; 10186e80c473SHans Verkuil 1019cb7a01acSMauro Carvalho Chehab /* scaling setting */ 1020cb7a01acSMauro Carvalho Chehab /* NTSC and interlace only */ 1021cb7a01acSMauro Carvalho Chehab prescale = SAA717X_NTSC_WIDTH / fmt->width; 1022cb7a01acSMauro Carvalho Chehab if (prescale == 0) 1023cb7a01acSMauro Carvalho Chehab prescale = 1; 1024cb7a01acSMauro Carvalho Chehab h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / fmt->width; 1025cb7a01acSMauro Carvalho Chehab /* interlace */ 1026cb7a01acSMauro Carvalho Chehab v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / fmt->height; 1027cb7a01acSMauro Carvalho Chehab 1028cb7a01acSMauro Carvalho Chehab /* Horizontal prescaling etc */ 1029cb7a01acSMauro Carvalho Chehab set_h_prescale(sd, 0, prescale); 1030cb7a01acSMauro Carvalho Chehab set_h_prescale(sd, 1, prescale); 1031cb7a01acSMauro Carvalho Chehab 1032cb7a01acSMauro Carvalho Chehab /* Horizontal scaling increment */ 1033cb7a01acSMauro Carvalho Chehab /* TASK A */ 1034cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF)); 1035cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF)); 1036cb7a01acSMauro Carvalho Chehab /* TASK B */ 1037cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF)); 1038cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF)); 1039cb7a01acSMauro Carvalho Chehab 1040cb7a01acSMauro Carvalho Chehab /* Vertical prescaling etc */ 1041cb7a01acSMauro Carvalho Chehab set_v_scale(sd, 0, v_scale); 1042cb7a01acSMauro Carvalho Chehab set_v_scale(sd, 1, v_scale); 1043cb7a01acSMauro Carvalho Chehab 1044cb7a01acSMauro Carvalho Chehab /* set video output size */ 1045cb7a01acSMauro Carvalho Chehab /* video number of pixels at output */ 1046cb7a01acSMauro Carvalho Chehab /* TASK A */ 1047cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5C, (u8)(fmt->width & 0xFF)); 1048cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5D, (u8)((fmt->width >> 8) & 0xFF)); 1049cb7a01acSMauro Carvalho Chehab /* TASK B */ 1050cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x9C, (u8)(fmt->width & 0xFF)); 1051cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x9D, (u8)((fmt->width >> 8) & 0xFF)); 1052cb7a01acSMauro Carvalho Chehab 1053cb7a01acSMauro Carvalho Chehab /* video number of lines at output */ 1054cb7a01acSMauro Carvalho Chehab /* TASK A */ 1055cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5E, (u8)(fmt->height & 0xFF)); 1056cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5F, (u8)((fmt->height >> 8) & 0xFF)); 1057cb7a01acSMauro Carvalho Chehab /* TASK B */ 1058cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x9E, (u8)(fmt->height & 0xFF)); 1059cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x9F, (u8)((fmt->height >> 8) & 0xFF)); 1060cb7a01acSMauro Carvalho Chehab return 0; 1061cb7a01acSMauro Carvalho Chehab } 1062cb7a01acSMauro Carvalho Chehab 1063cb7a01acSMauro Carvalho Chehab static int saa717x_s_radio(struct v4l2_subdev *sd) 1064cb7a01acSMauro Carvalho Chehab { 1065cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 1066cb7a01acSMauro Carvalho Chehab 1067cb7a01acSMauro Carvalho Chehab decoder->radio = 1; 1068cb7a01acSMauro Carvalho Chehab return 0; 1069cb7a01acSMauro Carvalho Chehab } 1070cb7a01acSMauro Carvalho Chehab 1071cb7a01acSMauro Carvalho Chehab static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 1072cb7a01acSMauro Carvalho Chehab { 1073cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 1074cb7a01acSMauro Carvalho Chehab 1075cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "decoder set norm "); 1076cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "(not yet implementd)\n"); 1077cb7a01acSMauro Carvalho Chehab 1078cb7a01acSMauro Carvalho Chehab decoder->radio = 0; 1079cb7a01acSMauro Carvalho Chehab decoder->std = std; 1080cb7a01acSMauro Carvalho Chehab return 0; 1081cb7a01acSMauro Carvalho Chehab } 1082cb7a01acSMauro Carvalho Chehab 1083cb7a01acSMauro Carvalho Chehab static int saa717x_s_audio_routing(struct v4l2_subdev *sd, 1084cb7a01acSMauro Carvalho Chehab u32 input, u32 output, u32 config) 1085cb7a01acSMauro Carvalho Chehab { 1086cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 1087cb7a01acSMauro Carvalho Chehab 1088cb7a01acSMauro Carvalho Chehab if (input < 3) { /* FIXME! --tadachi */ 1089cb7a01acSMauro Carvalho Chehab decoder->audio_input = input; 1090cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, 1091cb7a01acSMauro Carvalho Chehab "set decoder audio input to %d\n", 1092cb7a01acSMauro Carvalho Chehab decoder->audio_input); 1093cb7a01acSMauro Carvalho Chehab set_audio_regs(sd, decoder); 1094cb7a01acSMauro Carvalho Chehab return 0; 1095cb7a01acSMauro Carvalho Chehab } 1096cb7a01acSMauro Carvalho Chehab return -ERANGE; 1097cb7a01acSMauro Carvalho Chehab } 1098cb7a01acSMauro Carvalho Chehab 1099cb7a01acSMauro Carvalho Chehab static int saa717x_s_stream(struct v4l2_subdev *sd, int enable) 1100cb7a01acSMauro Carvalho Chehab { 1101cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 1102cb7a01acSMauro Carvalho Chehab 1103cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "decoder %s output\n", 1104cb7a01acSMauro Carvalho Chehab enable ? "enable" : "disable"); 1105cb7a01acSMauro Carvalho Chehab decoder->enable = enable; 1106cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26); 1107cb7a01acSMauro Carvalho Chehab return 0; 1108cb7a01acSMauro Carvalho Chehab } 1109cb7a01acSMauro Carvalho Chehab 1110cb7a01acSMauro Carvalho Chehab /* change audio mode */ 11112f73c7c5SHans Verkuil static int saa717x_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt) 1112cb7a01acSMauro Carvalho Chehab { 1113cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 1114cb7a01acSMauro Carvalho Chehab int audio_mode; 1115cb7a01acSMauro Carvalho Chehab char *mes[4] = { 1116cb7a01acSMauro Carvalho Chehab "MONO", "STEREO", "LANG1", "LANG2/SAP" 1117cb7a01acSMauro Carvalho Chehab }; 1118cb7a01acSMauro Carvalho Chehab 1119cb7a01acSMauro Carvalho Chehab audio_mode = TUNER_AUDIO_STEREO; 1120cb7a01acSMauro Carvalho Chehab 1121cb7a01acSMauro Carvalho Chehab switch (vt->audmode) { 1122cb7a01acSMauro Carvalho Chehab case V4L2_TUNER_MODE_MONO: 1123cb7a01acSMauro Carvalho Chehab audio_mode = TUNER_AUDIO_MONO; 1124cb7a01acSMauro Carvalho Chehab break; 1125cb7a01acSMauro Carvalho Chehab case V4L2_TUNER_MODE_STEREO: 1126cb7a01acSMauro Carvalho Chehab audio_mode = TUNER_AUDIO_STEREO; 1127cb7a01acSMauro Carvalho Chehab break; 1128cb7a01acSMauro Carvalho Chehab case V4L2_TUNER_MODE_LANG2: 1129cb7a01acSMauro Carvalho Chehab audio_mode = TUNER_AUDIO_LANG2; 1130cb7a01acSMauro Carvalho Chehab break; 1131cb7a01acSMauro Carvalho Chehab case V4L2_TUNER_MODE_LANG1: 1132cb7a01acSMauro Carvalho Chehab audio_mode = TUNER_AUDIO_LANG1; 1133cb7a01acSMauro Carvalho Chehab break; 1134cb7a01acSMauro Carvalho Chehab } 1135cb7a01acSMauro Carvalho Chehab 1136cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "change audio mode to %s\n", 1137cb7a01acSMauro Carvalho Chehab mes[audio_mode]); 1138cb7a01acSMauro Carvalho Chehab decoder->tuner_audio_mode = audio_mode; 1139cb7a01acSMauro Carvalho Chehab /* The registers are not changed here. */ 1140cb7a01acSMauro Carvalho Chehab /* See DECODER_ENABLE_OUTPUT section. */ 1141cb7a01acSMauro Carvalho Chehab set_audio_mode(sd, decoder->tuner_audio_mode); 1142cb7a01acSMauro Carvalho Chehab return 0; 1143cb7a01acSMauro Carvalho Chehab } 1144cb7a01acSMauro Carvalho Chehab 1145cb7a01acSMauro Carvalho Chehab static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) 1146cb7a01acSMauro Carvalho Chehab { 1147cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder = to_state(sd); 1148cb7a01acSMauro Carvalho Chehab int dual_f, stereo_f; 1149cb7a01acSMauro Carvalho Chehab 1150cb7a01acSMauro Carvalho Chehab if (decoder->radio) 1151cb7a01acSMauro Carvalho Chehab return 0; 1152cb7a01acSMauro Carvalho Chehab get_inf_dev_status(sd, &dual_f, &stereo_f); 1153cb7a01acSMauro Carvalho Chehab 1154cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n", 1155cb7a01acSMauro Carvalho Chehab stereo_f, dual_f); 1156cb7a01acSMauro Carvalho Chehab 1157cb7a01acSMauro Carvalho Chehab /* mono */ 1158cb7a01acSMauro Carvalho Chehab if ((dual_f == 0) && (stereo_f == 0)) { 1159cb7a01acSMauro Carvalho Chehab vt->rxsubchans = V4L2_TUNER_SUB_MONO; 1160cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DETECT==MONO\n"); 1161cb7a01acSMauro Carvalho Chehab } 1162cb7a01acSMauro Carvalho Chehab 1163cb7a01acSMauro Carvalho Chehab /* stereo */ 1164cb7a01acSMauro Carvalho Chehab if (stereo_f == 1) { 1165cb7a01acSMauro Carvalho Chehab if (vt->audmode == V4L2_TUNER_MODE_STEREO || 1166cb7a01acSMauro Carvalho Chehab vt->audmode == V4L2_TUNER_MODE_LANG1) { 1167cb7a01acSMauro Carvalho Chehab vt->rxsubchans = V4L2_TUNER_SUB_STEREO; 1168cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n"); 1169cb7a01acSMauro Carvalho Chehab } else { 1170cb7a01acSMauro Carvalho Chehab vt->rxsubchans = V4L2_TUNER_SUB_MONO; 1171cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n"); 1172cb7a01acSMauro Carvalho Chehab } 1173cb7a01acSMauro Carvalho Chehab } 1174cb7a01acSMauro Carvalho Chehab 1175cb7a01acSMauro Carvalho Chehab /* dual */ 1176cb7a01acSMauro Carvalho Chehab if (dual_f == 1) { 1177cb7a01acSMauro Carvalho Chehab if (vt->audmode == V4L2_TUNER_MODE_LANG2) { 1178cb7a01acSMauro Carvalho Chehab vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO; 1179cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n"); 1180cb7a01acSMauro Carvalho Chehab } else { 1181cb7a01acSMauro Carvalho Chehab vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO; 1182cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n"); 1183cb7a01acSMauro Carvalho Chehab } 1184cb7a01acSMauro Carvalho Chehab } 1185cb7a01acSMauro Carvalho Chehab return 0; 1186cb7a01acSMauro Carvalho Chehab } 1187cb7a01acSMauro Carvalho Chehab 1188cb7a01acSMauro Carvalho Chehab static int saa717x_log_status(struct v4l2_subdev *sd) 1189cb7a01acSMauro Carvalho Chehab { 1190cb7a01acSMauro Carvalho Chehab struct saa717x_state *state = to_state(sd); 1191cb7a01acSMauro Carvalho Chehab 1192cb7a01acSMauro Carvalho Chehab v4l2_ctrl_handler_log_status(&state->hdl, sd->name); 1193cb7a01acSMauro Carvalho Chehab return 0; 1194cb7a01acSMauro Carvalho Chehab } 1195cb7a01acSMauro Carvalho Chehab 1196cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 1197cb7a01acSMauro Carvalho Chehab 1198cb7a01acSMauro Carvalho Chehab static const struct v4l2_ctrl_ops saa717x_ctrl_ops = { 1199cb7a01acSMauro Carvalho Chehab .s_ctrl = saa717x_s_ctrl, 1200cb7a01acSMauro Carvalho Chehab }; 1201cb7a01acSMauro Carvalho Chehab 1202cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_core_ops saa717x_core_ops = { 1203cb7a01acSMauro Carvalho Chehab #ifdef CONFIG_VIDEO_ADV_DEBUG 1204cb7a01acSMauro Carvalho Chehab .g_register = saa717x_g_register, 1205cb7a01acSMauro Carvalho Chehab .s_register = saa717x_s_register, 1206cb7a01acSMauro Carvalho Chehab #endif 1207cb7a01acSMauro Carvalho Chehab .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, 1208cb7a01acSMauro Carvalho Chehab .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, 1209cb7a01acSMauro Carvalho Chehab .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, 1210cb7a01acSMauro Carvalho Chehab .g_ctrl = v4l2_subdev_g_ctrl, 1211cb7a01acSMauro Carvalho Chehab .s_ctrl = v4l2_subdev_s_ctrl, 1212cb7a01acSMauro Carvalho Chehab .queryctrl = v4l2_subdev_queryctrl, 1213cb7a01acSMauro Carvalho Chehab .querymenu = v4l2_subdev_querymenu, 1214cb7a01acSMauro Carvalho Chehab .log_status = saa717x_log_status, 1215cb7a01acSMauro Carvalho Chehab }; 1216cb7a01acSMauro Carvalho Chehab 1217cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = { 1218cb7a01acSMauro Carvalho Chehab .g_tuner = saa717x_g_tuner, 1219cb7a01acSMauro Carvalho Chehab .s_tuner = saa717x_s_tuner, 1220cb7a01acSMauro Carvalho Chehab .s_radio = saa717x_s_radio, 1221cb7a01acSMauro Carvalho Chehab }; 1222cb7a01acSMauro Carvalho Chehab 1223cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_video_ops saa717x_video_ops = { 12248774bed9SLaurent Pinchart .s_std = saa717x_s_std, 1225cb7a01acSMauro Carvalho Chehab .s_routing = saa717x_s_video_routing, 1226cb7a01acSMauro Carvalho Chehab .s_stream = saa717x_s_stream, 1227cb7a01acSMauro Carvalho Chehab }; 1228cb7a01acSMauro Carvalho Chehab 1229cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_audio_ops saa717x_audio_ops = { 1230cb7a01acSMauro Carvalho Chehab .s_routing = saa717x_s_audio_routing, 1231cb7a01acSMauro Carvalho Chehab }; 1232cb7a01acSMauro Carvalho Chehab 12336e80c473SHans Verkuil static const struct v4l2_subdev_pad_ops saa717x_pad_ops = { 12346e80c473SHans Verkuil .set_fmt = saa717x_set_fmt, 12356e80c473SHans Verkuil }; 12366e80c473SHans Verkuil 1237cb7a01acSMauro Carvalho Chehab static const struct v4l2_subdev_ops saa717x_ops = { 1238cb7a01acSMauro Carvalho Chehab .core = &saa717x_core_ops, 1239cb7a01acSMauro Carvalho Chehab .tuner = &saa717x_tuner_ops, 1240cb7a01acSMauro Carvalho Chehab .audio = &saa717x_audio_ops, 1241cb7a01acSMauro Carvalho Chehab .video = &saa717x_video_ops, 12426e80c473SHans Verkuil .pad = &saa717x_pad_ops, 1243cb7a01acSMauro Carvalho Chehab }; 1244cb7a01acSMauro Carvalho Chehab 1245cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 1246cb7a01acSMauro Carvalho Chehab 1247cb7a01acSMauro Carvalho Chehab 1248cb7a01acSMauro Carvalho Chehab /* i2c implementation */ 1249cb7a01acSMauro Carvalho Chehab 1250cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 1251cb7a01acSMauro Carvalho Chehab static int saa717x_probe(struct i2c_client *client, 1252cb7a01acSMauro Carvalho Chehab const struct i2c_device_id *did) 1253cb7a01acSMauro Carvalho Chehab { 1254cb7a01acSMauro Carvalho Chehab struct saa717x_state *decoder; 1255cb7a01acSMauro Carvalho Chehab struct v4l2_ctrl_handler *hdl; 1256cb7a01acSMauro Carvalho Chehab struct v4l2_subdev *sd; 1257cb7a01acSMauro Carvalho Chehab u8 id = 0; 1258cb7a01acSMauro Carvalho Chehab char *p = ""; 1259cb7a01acSMauro Carvalho Chehab 1260cb7a01acSMauro Carvalho Chehab /* Check if the adapter supports the needed features */ 1261cb7a01acSMauro Carvalho Chehab if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1262cb7a01acSMauro Carvalho Chehab return -EIO; 1263cb7a01acSMauro Carvalho Chehab 1264c02b211dSLaurent Pinchart decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL); 1265cb7a01acSMauro Carvalho Chehab if (decoder == NULL) 1266cb7a01acSMauro Carvalho Chehab return -ENOMEM; 1267cb7a01acSMauro Carvalho Chehab 1268cb7a01acSMauro Carvalho Chehab sd = &decoder->sd; 1269cb7a01acSMauro Carvalho Chehab v4l2_i2c_subdev_init(sd, client, &saa717x_ops); 1270cb7a01acSMauro Carvalho Chehab 1271cb7a01acSMauro Carvalho Chehab if (saa717x_write(sd, 0x5a4, 0xfe) && 1272cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5a5, 0x0f) && 1273cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5a6, 0x00) && 1274cb7a01acSMauro Carvalho Chehab saa717x_write(sd, 0x5a7, 0x01)) 1275cb7a01acSMauro Carvalho Chehab id = saa717x_read(sd, 0x5a0); 1276cb7a01acSMauro Carvalho Chehab if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) { 1277cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id); 1278cb7a01acSMauro Carvalho Chehab return -ENODEV; 1279cb7a01acSMauro Carvalho Chehab } 1280cb7a01acSMauro Carvalho Chehab if (id == 0xc2) 1281cb7a01acSMauro Carvalho Chehab p = "saa7173"; 1282cb7a01acSMauro Carvalho Chehab else if (id == 0x32) 1283cb7a01acSMauro Carvalho Chehab p = "saa7174A"; 1284cb7a01acSMauro Carvalho Chehab else if (id == 0x6c) 1285cb7a01acSMauro Carvalho Chehab p = "saa7174HL"; 1286cb7a01acSMauro Carvalho Chehab else 1287cb7a01acSMauro Carvalho Chehab p = "saa7171"; 1288cb7a01acSMauro Carvalho Chehab v4l2_info(sd, "%s found @ 0x%x (%s)\n", p, 1289cb7a01acSMauro Carvalho Chehab client->addr << 1, client->adapter->name); 1290cb7a01acSMauro Carvalho Chehab 1291cb7a01acSMauro Carvalho Chehab hdl = &decoder->hdl; 1292cb7a01acSMauro Carvalho Chehab v4l2_ctrl_handler_init(hdl, 9); 1293cb7a01acSMauro Carvalho Chehab /* add in ascending ID order */ 1294cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1295cb7a01acSMauro Carvalho Chehab V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); 1296cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1297cb7a01acSMauro Carvalho Chehab V4L2_CID_CONTRAST, 0, 255, 1, 68); 1298cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1299cb7a01acSMauro Carvalho Chehab V4L2_CID_SATURATION, 0, 255, 1, 64); 1300cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1301cb7a01acSMauro Carvalho Chehab V4L2_CID_HUE, -128, 127, 1, 0); 1302cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1303cb7a01acSMauro Carvalho Chehab V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 42000); 1304cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1305cb7a01acSMauro Carvalho Chehab V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768); 1306cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1307cb7a01acSMauro Carvalho Chehab V4L2_CID_AUDIO_BASS, -16, 15, 1, 0); 1308cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1309cb7a01acSMauro Carvalho Chehab V4L2_CID_AUDIO_TREBLE, -16, 15, 1, 0); 1310cb7a01acSMauro Carvalho Chehab v4l2_ctrl_new_std(hdl, &saa717x_ctrl_ops, 1311cb7a01acSMauro Carvalho Chehab V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); 1312cb7a01acSMauro Carvalho Chehab sd->ctrl_handler = hdl; 1313cb7a01acSMauro Carvalho Chehab if (hdl->error) { 1314cb7a01acSMauro Carvalho Chehab int err = hdl->error; 1315cb7a01acSMauro Carvalho Chehab 1316cb7a01acSMauro Carvalho Chehab v4l2_ctrl_handler_free(hdl); 1317cb7a01acSMauro Carvalho Chehab return err; 1318cb7a01acSMauro Carvalho Chehab } 1319cb7a01acSMauro Carvalho Chehab 1320cb7a01acSMauro Carvalho Chehab decoder->std = V4L2_STD_NTSC; 1321cb7a01acSMauro Carvalho Chehab decoder->input = -1; 1322cb7a01acSMauro Carvalho Chehab decoder->enable = 1; 1323cb7a01acSMauro Carvalho Chehab 1324cb7a01acSMauro Carvalho Chehab /* FIXME!! */ 1325cb7a01acSMauro Carvalho Chehab decoder->playback = 0; /* initially capture mode used */ 1326cb7a01acSMauro Carvalho Chehab decoder->audio = 1; /* DECODER_AUDIO_48_KHZ */ 1327cb7a01acSMauro Carvalho Chehab 1328cb7a01acSMauro Carvalho Chehab decoder->audio_input = 2; /* FIXME!! */ 1329cb7a01acSMauro Carvalho Chehab 1330cb7a01acSMauro Carvalho Chehab decoder->tuner_audio_mode = TUNER_AUDIO_STEREO; 1331cb7a01acSMauro Carvalho Chehab /* set volume, bass and treble */ 1332cb7a01acSMauro Carvalho Chehab decoder->audio_main_vol_l = 6; 1333cb7a01acSMauro Carvalho Chehab decoder->audio_main_vol_r = 6; 1334cb7a01acSMauro Carvalho Chehab 1335cb7a01acSMauro Carvalho Chehab v4l2_dbg(1, debug, sd, "writing init values\n"); 1336cb7a01acSMauro Carvalho Chehab 1337cb7a01acSMauro Carvalho Chehab /* FIXME!! */ 1338cb7a01acSMauro Carvalho Chehab saa717x_write_regs(sd, reg_init_initialize); 1339cb7a01acSMauro Carvalho Chehab 1340cb7a01acSMauro Carvalho Chehab v4l2_ctrl_handler_setup(hdl); 1341cb7a01acSMauro Carvalho Chehab 1342cb7a01acSMauro Carvalho Chehab set_current_state(TASK_INTERRUPTIBLE); 1343cb7a01acSMauro Carvalho Chehab schedule_timeout(2*HZ); 1344cb7a01acSMauro Carvalho Chehab return 0; 1345cb7a01acSMauro Carvalho Chehab } 1346cb7a01acSMauro Carvalho Chehab 1347cb7a01acSMauro Carvalho Chehab static int saa717x_remove(struct i2c_client *client) 1348cb7a01acSMauro Carvalho Chehab { 1349cb7a01acSMauro Carvalho Chehab struct v4l2_subdev *sd = i2c_get_clientdata(client); 1350cb7a01acSMauro Carvalho Chehab 1351cb7a01acSMauro Carvalho Chehab v4l2_device_unregister_subdev(sd); 1352cb7a01acSMauro Carvalho Chehab v4l2_ctrl_handler_free(sd->ctrl_handler); 1353cb7a01acSMauro Carvalho Chehab return 0; 1354cb7a01acSMauro Carvalho Chehab } 1355cb7a01acSMauro Carvalho Chehab 1356cb7a01acSMauro Carvalho Chehab /* ----------------------------------------------------------------------- */ 1357cb7a01acSMauro Carvalho Chehab 1358cb7a01acSMauro Carvalho Chehab static const struct i2c_device_id saa717x_id[] = { 1359cb7a01acSMauro Carvalho Chehab { "saa717x", 0 }, 1360cb7a01acSMauro Carvalho Chehab { } 1361cb7a01acSMauro Carvalho Chehab }; 1362cb7a01acSMauro Carvalho Chehab MODULE_DEVICE_TABLE(i2c, saa717x_id); 1363cb7a01acSMauro Carvalho Chehab 1364cb7a01acSMauro Carvalho Chehab static struct i2c_driver saa717x_driver = { 1365cb7a01acSMauro Carvalho Chehab .driver = { 1366cb7a01acSMauro Carvalho Chehab .owner = THIS_MODULE, 1367cb7a01acSMauro Carvalho Chehab .name = "saa717x", 1368cb7a01acSMauro Carvalho Chehab }, 1369cb7a01acSMauro Carvalho Chehab .probe = saa717x_probe, 1370cb7a01acSMauro Carvalho Chehab .remove = saa717x_remove, 1371cb7a01acSMauro Carvalho Chehab .id_table = saa717x_id, 1372cb7a01acSMauro Carvalho Chehab }; 1373cb7a01acSMauro Carvalho Chehab 1374cb7a01acSMauro Carvalho Chehab module_i2c_driver(saa717x_driver); 1375