Commit | Line | Data |
---|---|---|
73d9f979 HV |
1 | /* |
2 | * Copyright (C) 2005-2006 Micronas USA Inc. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License (Version 2) as | |
6 | * published by the Free Software Foundation. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU General Public License | |
14 | * along with this program; if not, write to the Free Software Foundation, | |
15 | * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | |
16 | */ | |
17 | ||
18 | #include <linux/module.h> | |
19 | #include <linux/init.h> | |
20 | #include <linux/i2c.h> | |
21 | #include <linux/videodev2.h> | |
22 | #include <media/v4l2-device.h> | |
23 | #include <media/uda1342.h> | |
24 | #include <linux/slab.h> | |
25 | ||
26 | static int write_reg(struct i2c_client *client, int reg, int value) | |
27 | { | |
28 | /* UDA1342 wants MSB first, but SMBus sends LSB first */ | |
29 | i2c_smbus_write_word_data(client, reg, swab16(value)); | |
30 | return 0; | |
31 | } | |
32 | ||
33 | static int uda1342_s_routing(struct v4l2_subdev *sd, | |
34 | u32 input, u32 output, u32 config) | |
35 | { | |
36 | struct i2c_client *client = v4l2_get_subdevdata(sd); | |
37 | ||
38 | switch (input) { | |
39 | case UDA1342_IN1: | |
40 | write_reg(client, 0x00, 0x1241); /* select input 1 */ | |
41 | break; | |
42 | case UDA1342_IN2: | |
43 | write_reg(client, 0x00, 0x1441); /* select input 2 */ | |
44 | break; | |
45 | default: | |
46 | v4l2_err(sd, "input %d not supported\n", input); | |
47 | break; | |
48 | } | |
49 | return 0; | |
50 | } | |
51 | ||
52 | static const struct v4l2_subdev_audio_ops uda1342_audio_ops = { | |
53 | .s_routing = uda1342_s_routing, | |
54 | }; | |
55 | ||
56 | static const struct v4l2_subdev_ops uda1342_ops = { | |
57 | .audio = &uda1342_audio_ops, | |
58 | }; | |
59 | ||
60 | static int uda1342_probe(struct i2c_client *client, | |
61 | const struct i2c_device_id *id) | |
62 | { | |
63 | struct i2c_adapter *adapter = client->adapter; | |
64 | struct v4l2_subdev *sd; | |
65 | ||
66 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) | |
67 | return -ENODEV; | |
68 | ||
69 | dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n", | |
70 | client->addr, adapter->name); | |
71 | ||
c02b211d | 72 | sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL); |
73d9f979 HV |
73 | if (sd == NULL) |
74 | return -ENOMEM; | |
75 | ||
76 | v4l2_i2c_subdev_init(sd, client, &uda1342_ops); | |
77 | ||
78 | write_reg(client, 0x00, 0x8000); /* reset registers */ | |
79 | write_reg(client, 0x00, 0x1241); /* select input 1 */ | |
80 | ||
81 | v4l_info(client, "chip found @ 0x%02x (%s)\n", | |
82 | client->addr << 1, client->adapter->name); | |
83 | ||
84 | return 0; | |
85 | } | |
86 | ||
87 | static int uda1342_remove(struct i2c_client *client) | |
88 | { | |
89 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | |
90 | ||
91 | v4l2_device_unregister_subdev(sd); | |
73d9f979 HV |
92 | return 0; |
93 | } | |
94 | ||
95 | static const struct i2c_device_id uda1342_id[] = { | |
96 | { "uda1342", 0 }, | |
97 | { } | |
98 | }; | |
99 | MODULE_DEVICE_TABLE(i2c, uda1342_id); | |
100 | ||
101 | static struct i2c_driver uda1342_driver = { | |
102 | .driver = { | |
103 | .name = "uda1342", | |
104 | }, | |
105 | .probe = uda1342_probe, | |
106 | .remove = uda1342_remove, | |
107 | .id_table = uda1342_id, | |
108 | }; | |
109 | ||
110 | module_i2c_driver(uda1342_driver); | |
111 | ||
112 | MODULE_LICENSE("GPL v2"); |