Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (6486): m52790: add new Mitsubishi A/V switch i2c driver

This driver is used by the ASUS Falcon2 cx23416-based cards.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Hans Verkuil and committed by
Mauro Carvalho Chehab
761dacd2 4be2f470

+278
+9
drivers/media/video/Kconfig
··· 119 119 To compile this driver as a module, choose M here: the 120 120 module will be called cs53l32a. 121 121 122 + config VIDEO_M52790 123 + tristate "Mitsubishi M52790 A/V switch" 124 + depends on VIDEO_V4L2 && I2C && EXPERIMENTAL 125 + ---help--- 126 + Support for the Mitsubishi M52790 A/V switch. 127 + 128 + To compile this driver as a module, choose M here: the 129 + module will be called m52790. 130 + 122 131 config VIDEO_TLV320AIC23B 123 132 tristate "Texas Instruments TLV320AIC23B audio codec" 124 133 depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+1
drivers/media/video/Makefile
··· 67 67 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 68 68 obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o 69 69 obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o 70 + obj-$(CONFIG_VIDEO_M52790) += m52790.o 70 71 obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o 71 72 obj-$(CONFIG_VIDEO_WM8775) += wm8775.o 72 73 obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+172
drivers/media/video/m52790.c
··· 1 + /* 2 + * m52790 i2c ivtv driver. 3 + * Copyright (C) 2007 Hans Verkuil 4 + * 5 + * A/V source switching Mitsubishi M52790SP/FP 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 + */ 21 + 22 + 23 + #include <linux/module.h> 24 + #include <linux/types.h> 25 + #include <linux/ioctl.h> 26 + #include <asm/uaccess.h> 27 + #include <linux/i2c.h> 28 + #include <linux/i2c-id.h> 29 + #include <linux/videodev.h> 30 + #include <media/m52790.h> 31 + #include <media/v4l2-common.h> 32 + #include <media/v4l2-chip-ident.h> 33 + #include <media/v4l2-i2c-drv-legacy.h> 34 + 35 + MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch"); 36 + MODULE_AUTHOR("Hans Verkuil"); 37 + MODULE_LICENSE("GPL"); 38 + 39 + static unsigned short normal_i2c[] = { 0x90 >> 1, I2C_CLIENT_END }; 40 + 41 + 42 + I2C_CLIENT_INSMOD; 43 + 44 + struct m52790_state { 45 + u16 input; 46 + u16 output; 47 + }; 48 + 49 + /* ----------------------------------------------------------------------- */ 50 + 51 + static int m52790_write(struct i2c_client *client) 52 + { 53 + struct m52790_state *state = i2c_get_clientdata(client); 54 + u8 sw1 = (state->input | state->output) & 0xff; 55 + u8 sw2 = (state->input | state->output) >> 8; 56 + 57 + return i2c_smbus_write_byte_data(client, sw1, sw2); 58 + } 59 + 60 + static int m52790_command(struct i2c_client *client, unsigned int cmd, 61 + void *arg) 62 + { 63 + struct m52790_state *state = i2c_get_clientdata(client); 64 + struct v4l2_routing *route = arg; 65 + 66 + /* Note: audio and video are linked and cannot be switched separately. 67 + So audio and video routing commands are identical for this chip. 68 + In theory the video amplifier and audio modes could be handled 69 + separately for the output, but that seems to be overkill right now. 70 + The same holds for implementing an audio mute control, this is now 71 + part of the audio output routing. The normal case is that another 72 + chip takes care of the actual muting so making it part of the 73 + output routing seems to be the right thing to do for now. */ 74 + switch (cmd) { 75 + case VIDIOC_INT_G_AUDIO_ROUTING: 76 + case VIDIOC_INT_G_VIDEO_ROUTING: 77 + route->input = state->input; 78 + route->output = state->output; 79 + break; 80 + 81 + case VIDIOC_INT_S_AUDIO_ROUTING: 82 + case VIDIOC_INT_S_VIDEO_ROUTING: 83 + state->input = route->input; 84 + state->output = route->output; 85 + m52790_write(client); 86 + break; 87 + 88 + #ifdef CONFIG_VIDEO_ADV_DEBUG 89 + case VIDIOC_DBG_G_REGISTER: 90 + case VIDIOC_DBG_S_REGISTER: 91 + { 92 + struct v4l2_register *reg = arg; 93 + 94 + if (!v4l2_chip_match_i2c_client(client, 95 + reg->match_type, reg->match_chip)) 96 + return -EINVAL; 97 + if (!capable(CAP_SYS_ADMIN)) 98 + return -EPERM; 99 + if (reg->reg != 0) 100 + return -EINVAL; 101 + if (cmd == VIDIOC_DBG_G_REGISTER) 102 + reg->val = state->input | state->output; 103 + else { 104 + state->input = reg->val & 0x0303; 105 + state->output = reg->val & ~0x0303; 106 + m52790_write(client); 107 + } 108 + break; 109 + } 110 + #endif 111 + 112 + case VIDIOC_G_CHIP_IDENT: 113 + return v4l2_chip_ident_i2c_client(client, arg, 114 + V4L2_IDENT_M52790, 0); 115 + 116 + case VIDIOC_LOG_STATUS: 117 + v4l_info(client, "Switch 1: %02x\n", 118 + (state->input | state->output) & 0xff); 119 + v4l_info(client, "Switch 2: %02x\n", 120 + (state->input | state->output) >> 8); 121 + break; 122 + 123 + default: 124 + return -EINVAL; 125 + } 126 + return 0; 127 + } 128 + 129 + /* ----------------------------------------------------------------------- */ 130 + 131 + /* i2c implementation */ 132 + 133 + static int m52790_probe(struct i2c_client *client) 134 + { 135 + struct m52790_state *state; 136 + 137 + /* Check if the adapter supports the needed features */ 138 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 139 + return -EIO; 140 + 141 + snprintf(client->name, sizeof(client->name) - 1, "m52790"); 142 + 143 + v4l_info(client, "chip found @ 0x%x (%s)\n", 144 + client->addr << 1, client->adapter->name); 145 + 146 + state = kmalloc(sizeof(struct m52790_state), GFP_KERNEL); 147 + if (state == NULL) 148 + return -ENOMEM; 149 + 150 + state->input = M52790_IN_TUNER; 151 + state->output = M52790_OUT_STEREO; 152 + i2c_set_clientdata(client, state); 153 + m52790_write(client); 154 + return 0; 155 + } 156 + 157 + static int m52790_remove(struct i2c_client *client) 158 + { 159 + kfree(i2c_get_clientdata(client)); 160 + return 0; 161 + } 162 + 163 + /* ----------------------------------------------------------------------- */ 164 + 165 + static struct v4l2_i2c_driver_data v4l2_i2c_data = { 166 + .name = "m52790", 167 + .driverid = I2C_DRIVERID_M52790, 168 + .command = m52790_command, 169 + .probe = m52790_probe, 170 + .remove = m52790_remove, 171 + }; 172 +
+93
include/media/m52790.h
··· 1 + /* 2 + m52790.h - definition for m52790 inputs and outputs 3 + 4 + Copyright (C) 2007 Hans Verkuil (hverkuil@xs4all.nl) 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with this program; if not, write to the Free Software 18 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #ifndef _M52790_H_ 22 + #define _M52790_H_ 23 + 24 + /* Input routing switch 1 */ 25 + 26 + #define M52790_SW1_IN_MASK 0x0003 27 + #define M52790_SW1_IN_TUNER 0x0000 28 + #define M52790_SW1_IN_V2 0x0001 29 + #define M52790_SW1_IN_V3 0x0002 30 + #define M52790_SW1_IN_V4 0x0003 31 + 32 + /* Selects component input instead of composite */ 33 + #define M52790_SW1_YCMIX 0x0004 34 + 35 + 36 + /* Input routing switch 2 */ 37 + 38 + #define M52790_SW2_IN_MASK 0x0300 39 + #define M52790_SW2_IN_TUNER 0x0000 40 + #define M52790_SW2_IN_V2 0x0100 41 + #define M52790_SW2_IN_V3 0x0200 42 + #define M52790_SW2_IN_V4 0x0300 43 + 44 + /* Selects component input instead of composite */ 45 + #define M52790_SW2_YCMIX 0x0400 46 + 47 + 48 + /* Output routing switch 1 */ 49 + 50 + /* Enable 6dB amplifier for composite out */ 51 + #define M52790_SW1_V_AMP 0x0008 52 + 53 + /* Enable 6dB amplifier for component out */ 54 + #define M52790_SW1_YC_AMP 0x0010 55 + 56 + /* Audio output mode */ 57 + #define M52790_SW1_AUDIO_MASK 0x00c0 58 + #define M52790_SW1_AUDIO_MUTE 0x0000 59 + #define M52790_SW1_AUDIO_R 0x0040 60 + #define M52790_SW1_AUDIO_L 0x0080 61 + #define M52790_SW1_AUDIO_STEREO 0x00c0 62 + 63 + 64 + /* Output routing switch 2 */ 65 + 66 + /* Enable 6dB amplifier for composite out */ 67 + #define M52790_SW2_V_AMP 0x0800 68 + 69 + /* Enable 6dB amplifier for component out */ 70 + #define M52790_SW2_YC_AMP 0x1000 71 + 72 + /* Audio output mode */ 73 + #define M52790_SW2_AUDIO_MASK 0xc000 74 + #define M52790_SW2_AUDIO_MUTE 0x0000 75 + #define M52790_SW2_AUDIO_R 0x4000 76 + #define M52790_SW2_AUDIO_L 0x8000 77 + #define M52790_SW2_AUDIO_STEREO 0xc000 78 + 79 + 80 + /* Common values */ 81 + #define M52790_IN_TUNER (M52790_SW1_IN_TUNER | M52790_SW2_IN_TUNER) 82 + #define M52790_IN_V2 (M52790_SW1_IN_V2 | M52790_SW2_IN_V2) 83 + #define M52790_IN_V3 (M52790_SW1_IN_V3 | M52790_SW2_IN_V3) 84 + #define M52790_IN_V4 (M52790_SW1_IN_V4 | M52790_SW2_IN_V4) 85 + 86 + #define M52790_OUT_STEREO (M52790_SW1_AUDIO_STEREO | \ 87 + M52790_SW2_AUDIO_STEREO) 88 + #define M52790_OUT_AMP_STEREO (M52790_SW1_AUDIO_STEREO | \ 89 + M52790_SW1_V_AMP | \ 90 + M52790_SW2_AUDIO_STEREO | \ 91 + M52790_SW2_V_AMP) 92 + 93 + #endif
+3
include/media/v4l2-chip-ident.h
··· 83 83 /* module upd64083: just ident 64083 */ 84 84 V4L2_IDENT_UPD64083 = 64083, 85 85 86 + /* module m52790: just ident 52790 */ 87 + V4L2_IDENT_M52790 = 52790, 88 + 86 89 /* module msp34xx: reserved range 34000-34999 */ 87 90 V4L2_IDENT_MSP3400B = 34002, 88 91 V4L2_IDENT_MSP3410B = 34102,