0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/types.h>
0012 #include <linux/slab.h>
0013 #include <linux/ioctl.h>
0014 #include <linux/uaccess.h>
0015 #include <linux/i2c.h>
0016 #include <linux/videodev2.h>
0017 #include <media/i2c/m52790.h>
0018 #include <media/v4l2-device.h>
0019
0020 MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");
0021 MODULE_AUTHOR("Hans Verkuil");
0022 MODULE_LICENSE("GPL");
0023
0024
0025 struct m52790_state {
0026 struct v4l2_subdev sd;
0027 u16 input;
0028 u16 output;
0029 };
0030
0031 static inline struct m52790_state *to_state(struct v4l2_subdev *sd)
0032 {
0033 return container_of(sd, struct m52790_state, sd);
0034 }
0035
0036
0037
0038 static int m52790_write(struct v4l2_subdev *sd)
0039 {
0040 struct m52790_state *state = to_state(sd);
0041 struct i2c_client *client = v4l2_get_subdevdata(sd);
0042
0043 u8 sw1 = (state->input | state->output) & 0xff;
0044 u8 sw2 = (state->input | state->output) >> 8;
0045
0046 return i2c_smbus_write_byte_data(client, sw1, sw2);
0047 }
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 static int m52790_s_routing(struct v4l2_subdev *sd,
0058 u32 input, u32 output, u32 config)
0059 {
0060 struct m52790_state *state = to_state(sd);
0061
0062 state->input = input;
0063 state->output = output;
0064 m52790_write(sd);
0065 return 0;
0066 }
0067
0068 #ifdef CONFIG_VIDEO_ADV_DEBUG
0069 static int m52790_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
0070 {
0071 struct m52790_state *state = to_state(sd);
0072
0073 if (reg->reg != 0)
0074 return -EINVAL;
0075 reg->size = 1;
0076 reg->val = state->input | state->output;
0077 return 0;
0078 }
0079
0080 static int m52790_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
0081 {
0082 struct m52790_state *state = to_state(sd);
0083
0084 if (reg->reg != 0)
0085 return -EINVAL;
0086 state->input = reg->val & 0x0303;
0087 state->output = reg->val & ~0x0303;
0088 m52790_write(sd);
0089 return 0;
0090 }
0091 #endif
0092
0093 static int m52790_log_status(struct v4l2_subdev *sd)
0094 {
0095 struct m52790_state *state = to_state(sd);
0096
0097 v4l2_info(sd, "Switch 1: %02x\n",
0098 (state->input | state->output) & 0xff);
0099 v4l2_info(sd, "Switch 2: %02x\n",
0100 (state->input | state->output) >> 8);
0101 return 0;
0102 }
0103
0104
0105
0106 static const struct v4l2_subdev_core_ops m52790_core_ops = {
0107 .log_status = m52790_log_status,
0108 #ifdef CONFIG_VIDEO_ADV_DEBUG
0109 .g_register = m52790_g_register,
0110 .s_register = m52790_s_register,
0111 #endif
0112 };
0113
0114 static const struct v4l2_subdev_audio_ops m52790_audio_ops = {
0115 .s_routing = m52790_s_routing,
0116 };
0117
0118 static const struct v4l2_subdev_video_ops m52790_video_ops = {
0119 .s_routing = m52790_s_routing,
0120 };
0121
0122 static const struct v4l2_subdev_ops m52790_ops = {
0123 .core = &m52790_core_ops,
0124 .audio = &m52790_audio_ops,
0125 .video = &m52790_video_ops,
0126 };
0127
0128
0129
0130
0131
0132 static int m52790_probe(struct i2c_client *client,
0133 const struct i2c_device_id *id)
0134 {
0135 struct m52790_state *state;
0136 struct v4l2_subdev *sd;
0137
0138
0139 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
0140 return -EIO;
0141
0142 v4l_info(client, "chip found @ 0x%x (%s)\n",
0143 client->addr << 1, client->adapter->name);
0144
0145 state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
0146 if (state == NULL)
0147 return -ENOMEM;
0148
0149 sd = &state->sd;
0150 v4l2_i2c_subdev_init(sd, client, &m52790_ops);
0151 state->input = M52790_IN_TUNER;
0152 state->output = M52790_OUT_STEREO;
0153 m52790_write(sd);
0154 return 0;
0155 }
0156
0157 static int m52790_remove(struct i2c_client *client)
0158 {
0159 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0160
0161 v4l2_device_unregister_subdev(sd);
0162 return 0;
0163 }
0164
0165
0166
0167 static const struct i2c_device_id m52790_id[] = {
0168 { "m52790", 0 },
0169 { }
0170 };
0171 MODULE_DEVICE_TABLE(i2c, m52790_id);
0172
0173 static struct i2c_driver m52790_driver = {
0174 .driver = {
0175 .name = "m52790",
0176 },
0177 .probe = m52790_probe,
0178 .remove = m52790_remove,
0179 .id_table = m52790_id,
0180 };
0181
0182 module_i2c_driver(m52790_driver);