1c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* 2c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Copyright (C) 2005-2006 Micronas USA Inc. 3c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 4c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * This program is free software; you can redistribute it and/or modify 5c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * it under the terms of the GNU General Public License (Version 2) as 6c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * published by the Free Software Foundation. 7c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 8c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * This program is distributed in the hope that it will be useful, 9c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * but WITHOUT ANY WARRANTY; without even the implied warranty of 10c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * GNU General Public License for more details. 12c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 13c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * You should have received a copy of the GNU General Public License 14c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * along with this program; if not, write to the Free Software Foundation, 15c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 16c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil */ 17c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 18c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <linux/module.h> 19c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <linux/init.h> 20c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <linux/i2c.h> 21c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <linux/videodev2.h> 22c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <media/tuner.h> 23c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <media/v4l2-common.h> 24c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <media/v4l2-ioctl.h> 25c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <media/v4l2-device.h> 26c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#include <linux/slab.h> 27c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 28c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans VerkuilMODULE_DESCRIPTION("sony-btf-mpx driver"); 29c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans VerkuilMODULE_LICENSE("GPL v2"); 30c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 31c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int debug; 32c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilmodule_param(debug, int, 0644); 335c75a55e3c2820f2fd7e256e577c1b528567f3aeJean DelvareMODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on"); 34c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 35c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* #define MPX_DEBUG */ 36c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 37c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* 38c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Note: 39c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 40c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * AS(IF/MPX) pin: LOW HIGH/OPEN 41c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * IF/MPX address: 0x42/0x40 0x43/0x44 42c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil */ 43c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 44c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 45c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int force_mpx_mode = -1; 46c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilmodule_param(force_mpx_mode, int, 0644); 47c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 48c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstruct sony_btf_mpx { 49c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct v4l2_subdev sd; 50c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil int mpxmode; 51c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u32 audmode; 52c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil}; 53c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 54c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd) 55c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 56c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return container_of(sd, struct sony_btf_mpx, sd); 57c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 58c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 59c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int mpx_write(struct i2c_client *client, int dev, int addr, int val) 60c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 61c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u8 buffer[5]; 62c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct i2c_msg msg; 63c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 64c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[0] = dev; 65c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[1] = addr >> 8; 66c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[2] = addr & 0xff; 67c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[3] = val >> 8; 68c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[4] = val & 0xff; 69c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.addr = client->addr; 70c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.flags = 0; 71c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.len = 5; 72c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.buf = buffer; 73c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil i2c_transfer(client->adapter, &msg, 1); 74c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 75c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 76c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 77c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* 78c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * MPX register values for the BTF-PG472Z: 79c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 80c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * FM_ NICAM_ SCART_ 81c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * MODUS SOURCE ACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME 82c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000 83c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * --------------------------------------------------------------- 84c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Auto 1003 0020 0100 2603 5000 XXXX 0001 7500 85c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 86c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * B/G 87c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Mono 1003 0020 0100 2603 5000 XXXX 0003 7500 88c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * A2 1003 0020 0100 2601 5000 XXXX 0003 7500 89c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * NICAM 1003 0120 0100 2603 5000 XXXX 0008 7500 90c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 91c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * I 92c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Mono 1003 0020 0100 2603 7900 XXXX 000A 7500 93c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * NICAM 1003 0120 0100 2603 7900 XXXX 000A 7500 94c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 95c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * D/K 96c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Mono 1003 0020 0100 2603 5000 XXXX 0004 7500 97c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * A2-1 1003 0020 0100 2601 5000 XXXX 0004 7500 98c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * A2-2 1003 0020 0100 2601 5000 XXXX 0005 7500 99c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * A2-3 1003 0020 0100 2601 5000 XXXX 0007 7500 100c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * NICAM 1003 0120 0100 2603 5000 XXXX 000B 7500 101c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 102c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * L/L' 103c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Mono 0003 0200 0100 7C03 5000 2200 0009 7500 104c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * NICAM 0003 0120 0100 7C03 5000 XXXX 0009 7500 105c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 106c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * M 107c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Mono 1003 0200 0100 2B03 5000 2B00 0002 7500 108c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 109c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX. 110c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 111c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Bilingual selection in A2/NICAM: 112c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 113c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * High byte of SOURCE Left chan Right chan 114c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 0x01 MAIN SUB 115c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 0x03 MAIN MAIN 116c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 0x04 SUB SUB 117c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 118c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or 119c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 0x00 (all other bands). Force mono in A2 with FMONO_A2: 120c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 121c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * FMONO_A2 122c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * 10/0022 123c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * -------- 124c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Forced mono ON 07F0 125c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil * Forced mono OFF 0190 126c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil */ 127c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 128c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic const struct { 129c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode; 130c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 modus; 131c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 source; 132c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 acb; 133c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 fm_prescale; 134c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 nicam_prescale; 135c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 scart_prescale; 136c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 system; 137c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 volume; 138c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} mpx_audio_modes[] = { 139c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* Auto */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603, 140c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0001, 0x7500 }, 141c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* B/G Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603, 142c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0003, 0x7500 }, 143c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* B/G A2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601, 144c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0003, 0x7500 }, 145c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* B/G NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603, 146c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0008, 0x7500 }, 147c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* I Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603, 148c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x7900, 0x0000, 0x000A, 0x7500 }, 149c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* I NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603, 150c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x7900, 0x0000, 0x000A, 0x7500 }, 151c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* D/K Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603, 152c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0004, 0x7500 }, 153c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* D/K A2-1 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601, 154c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0004, 0x7500 }, 155c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* D/K A2-2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601, 156c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0005, 0x7500 }, 157c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* D/K A2-3 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601, 158c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0007, 0x7500 }, 159c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* D/K NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603, 160c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x000B, 0x7500 }, 161c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* L/L' Mono */ { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03, 162c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x2200, 0x0009, 0x7500 }, 163c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* L/L' NICAM */{ AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03, 164c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 0x5000, 0x0000, 0x0009, 0x7500 }, 165c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil}; 166c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 167c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes) 168c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 169c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int mpx_setup(struct sony_btf_mpx *t) 170c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 171c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct i2c_client *client = v4l2_get_subdevdata(&t->sd); 172c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u16 source = 0; 173c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u8 buffer[3]; 174c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct i2c_msg msg; 175c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil int mode = t->mpxmode; 176c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 177c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* reset MPX */ 178c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[0] = 0x00; 179c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[1] = 0x80; 180c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[2] = 0x00; 181c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.addr = client->addr; 182c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.flags = 0; 183c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.len = 3; 184c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msg.buf = buffer; 185c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil i2c_transfer(client->adapter, &msg, 1); 186c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buffer[1] = 0x00; 187c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil i2c_transfer(client->adapter, &msg, 1); 188c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 189c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (t->audmode != V4L2_TUNER_MODE_MONO) 190c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mode++; 191c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 192c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (mpx_audio_modes[mode].audio_mode != AUD_MONO) { 193c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil switch (t->audmode) { 194c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case V4L2_TUNER_MODE_MONO: 195c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil switch (mpx_audio_modes[mode].audio_mode) { 196c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case AUD_A2: 197c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = mpx_audio_modes[mode].source; 198c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 199c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case AUD_NICAM: 200c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = 0x0000; 201c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 202c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case AUD_NICAM_L: 203c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = 0x0200; 204c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 205c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil default: 206c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 207c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil } 208c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 209c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case V4L2_TUNER_MODE_STEREO: 210c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = mpx_audio_modes[mode].source; 211c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 212c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case V4L2_TUNER_MODE_LANG1: 213c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = 0x0300; 214c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 215c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil case V4L2_TUNER_MODE_LANG2: 216c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = 0x0400; 217c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil break; 218c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil } 219c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source |= mpx_audio_modes[mode].source & 0x00ff; 220c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil } else 221c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source = mpx_audio_modes[mode].source; 222c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 223c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x10, 0x0030, mpx_audio_modes[mode].modus); 224c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x12, 0x0008, source); 225c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x12, 0x0013, mpx_audio_modes[mode].acb); 226c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x12, 0x000e, 227c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].fm_prescale); 228c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x12, 0x0010, 229c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].nicam_prescale); 230c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x12, 0x000d, 231c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].scart_prescale); 232c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x10, 0x0020, mpx_audio_modes[mode].system); 233c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x12, 0x0000, mpx_audio_modes[mode].volume); 234c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (mpx_audio_modes[mode].audio_mode == AUD_A2) 235c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_write(client, 0x10, 0x0022, 236c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190); 237c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 238c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#ifdef MPX_DEBUG 239c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil { 240c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil u8 buf1[3], buf2[2]; 241c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct i2c_msg msgs[2]; 242c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 243c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil v4l2_info(client, 244c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil "MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n", 245c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].modus, 246c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil source, 247c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].acb, 248c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].fm_prescale, 249c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].nicam_prescale, 250c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].scart_prescale, 251c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].system, 252c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_audio_modes[mode].volume); 253c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf1[0] = 0x11; 254c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf1[1] = 0x00; 255c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf1[2] = 0x7e; 256c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[0].addr = client->addr; 257c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[0].flags = 0; 258c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[0].len = 3; 259c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[0].buf = buf1; 260c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[1].addr = client->addr; 261c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[1].flags = I2C_M_RD; 262c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[1].len = 2; 263c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil msgs[1].buf = buf2; 264c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil i2c_transfer(client->adapter, msgs, 2); 265c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil v4l2_info(client, "MPX system: %02x%02x\n", 266c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf2[0], buf2[1]); 267c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf1[0] = 0x11; 268c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf1[1] = 0x02; 269c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf1[2] = 0x00; 270c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil i2c_transfer(client->adapter, msgs, 2); 271c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil v4l2_info(client, "MPX status: %02x%02x\n", 272c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil buf2[0], buf2[1]); 273c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil } 274c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil#endif 275c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 276c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 277c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 278c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 279c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int sony_btf_mpx_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 280c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 281c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct sony_btf_mpx *t = to_state(sd); 282c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil int default_mpx_mode = 0; 283c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 284c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (std & V4L2_STD_PAL_BG) 285c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil default_mpx_mode = 1; 286c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil else if (std & V4L2_STD_PAL_I) 287c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil default_mpx_mode = 4; 288c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil else if (std & V4L2_STD_PAL_DK) 289c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil default_mpx_mode = 6; 290c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil else if (std & V4L2_STD_SECAM_L) 291c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil default_mpx_mode = 11; 292c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 293c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (default_mpx_mode != t->mpxmode) { 294c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil t->mpxmode = default_mpx_mode; 295c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_setup(t); 296c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil } 297c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 298c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 299c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 300c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int sony_btf_mpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) 301c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 302c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct sony_btf_mpx *t = to_state(sd); 303c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 304c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil vt->capability = V4L2_TUNER_CAP_NORM | 305c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | 306c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil V4L2_TUNER_CAP_LANG2; 307c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil vt->rxsubchans = V4L2_TUNER_SUB_MONO | 308c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 | 309c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil V4L2_TUNER_SUB_LANG2; 310c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil vt->audmode = t->audmode; 311c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 312c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 313c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 314b781e6be79a394cd6980e9cd8fd5c25822d152b6Mauro Carvalho Chehabstatic int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt) 315c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 316c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct sony_btf_mpx *t = to_state(sd); 317c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 318c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (vt->type != V4L2_TUNER_ANALOG_TV) 319c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return -EINVAL; 320c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 321c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (vt->audmode != t->audmode) { 322c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil t->audmode = vt->audmode; 323c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil mpx_setup(t); 324c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil } 325c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 326c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 327c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 328c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* --------------------------------------------------------------------------*/ 329c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 330c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = { 331c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .s_tuner = sony_btf_mpx_s_tuner, 332c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .g_tuner = sony_btf_mpx_g_tuner, 333c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil}; 334c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 3358774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchartstatic const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = { 3368774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart .s_std = sony_btf_mpx_s_std, 3378774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart}; 3388774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart 339c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic const struct v4l2_subdev_ops sony_btf_mpx_ops = { 340c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .tuner = &sony_btf_mpx_tuner_ops, 3418774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart .video = &sony_btf_mpx_video_ops, 342c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil}; 343c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 344c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* --------------------------------------------------------------------------*/ 345c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 346c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int sony_btf_mpx_probe(struct i2c_client *client, 347c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil const struct i2c_device_id *id) 348c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 349c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct sony_btf_mpx *t; 350c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct v4l2_subdev *sd; 351c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 352c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 353c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return -ENODEV; 354c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 355c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil v4l_info(client, "chip found @ 0x%x (%s)\n", 356c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil client->addr << 1, client->adapter->name); 357c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 358c02b211df6fc54e51ee554c27a6736a11255a764Laurent Pinchart t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL); 359c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil if (t == NULL) 360c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return -ENOMEM; 361c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 362c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil sd = &t->sd; 363c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil v4l2_i2c_subdev_init(sd, client, &sony_btf_mpx_ops); 364c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 365c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil /* Initialize sony_btf_mpx */ 366c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil t->mpxmode = 0; 367c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil t->audmode = V4L2_TUNER_MODE_STEREO; 368c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 369c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 370c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 371c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 372c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic int sony_btf_mpx_remove(struct i2c_client *client) 373c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil{ 374c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil struct v4l2_subdev *sd = i2c_get_clientdata(client); 375c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 376c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil v4l2_device_unregister_subdev(sd); 377c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 378c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil return 0; 379c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil} 380c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 381c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil/* ----------------------------------------------------------------------- */ 382c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 383c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic const struct i2c_device_id sony_btf_mpx_id[] = { 384c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil { "sony-btf-mpx", 0 }, 385c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil { } 386c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil}; 387c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans VerkuilMODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id); 388c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil 389c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilstatic struct i2c_driver sony_btf_mpx_driver = { 390c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .driver = { 391c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .owner = THIS_MODULE, 392c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .name = "sony-btf-mpx", 393c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil }, 394c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .probe = sony_btf_mpx_probe, 395c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .remove = sony_btf_mpx_remove, 396c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil .id_table = sony_btf_mpx_id, 397c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuil}; 398c7c54a988d21626874e9f1b8dc6bb0547bcddf9cHans Verkuilmodule_i2c_driver(sony_btf_mpx_driver); 399