]>
Commit | Line | Data |
---|---|---|
1802d0be | 1 | // SPDX-License-Identifier: GPL-2.0-only |
73d9f979 HV |
2 | /* |
3 | * Copyright (C) 2005-2006 Micronas USA Inc. | |
73d9f979 HV |
4 | */ |
5 | ||
6 | #include <linux/module.h> | |
7 | #include <linux/init.h> | |
8 | #include <linux/i2c.h> | |
9 | #include <linux/videodev2.h> | |
10 | #include <media/v4l2-device.h> | |
b5dcee22 | 11 | #include <media/i2c/uda1342.h> |
73d9f979 HV |
12 | #include <linux/slab.h> |
13 | ||
14 | static int write_reg(struct i2c_client *client, int reg, int value) | |
15 | { | |
16 | /* UDA1342 wants MSB first, but SMBus sends LSB first */ | |
17 | i2c_smbus_write_word_data(client, reg, swab16(value)); | |
18 | return 0; | |
19 | } | |
20 | ||
21 | static int uda1342_s_routing(struct v4l2_subdev *sd, | |
22 | u32 input, u32 output, u32 config) | |
23 | { | |
24 | struct i2c_client *client = v4l2_get_subdevdata(sd); | |
25 | ||
26 | switch (input) { | |
27 | case UDA1342_IN1: | |
28 | write_reg(client, 0x00, 0x1241); /* select input 1 */ | |
29 | break; | |
30 | case UDA1342_IN2: | |
31 | write_reg(client, 0x00, 0x1441); /* select input 2 */ | |
32 | break; | |
33 | default: | |
34 | v4l2_err(sd, "input %d not supported\n", input); | |
35 | break; | |
36 | } | |
37 | return 0; | |
38 | } | |
39 | ||
40 | static const struct v4l2_subdev_audio_ops uda1342_audio_ops = { | |
41 | .s_routing = uda1342_s_routing, | |
42 | }; | |
43 | ||
44 | static const struct v4l2_subdev_ops uda1342_ops = { | |
45 | .audio = &uda1342_audio_ops, | |
46 | }; | |
47 | ||
48 | static int uda1342_probe(struct i2c_client *client, | |
49 | const struct i2c_device_id *id) | |
50 | { | |
51 | struct i2c_adapter *adapter = client->adapter; | |
52 | struct v4l2_subdev *sd; | |
53 | ||
54 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) | |
55 | return -ENODEV; | |
56 | ||
57 | dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n", | |
58 | client->addr, adapter->name); | |
59 | ||
c02b211d | 60 | sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL); |
73d9f979 HV |
61 | if (sd == NULL) |
62 | return -ENOMEM; | |
63 | ||
64 | v4l2_i2c_subdev_init(sd, client, &uda1342_ops); | |
65 | ||
66 | write_reg(client, 0x00, 0x8000); /* reset registers */ | |
67 | write_reg(client, 0x00, 0x1241); /* select input 1 */ | |
68 | ||
69 | v4l_info(client, "chip found @ 0x%02x (%s)\n", | |
70 | client->addr << 1, client->adapter->name); | |
71 | ||
72 | return 0; | |
73 | } | |
74 | ||
75 | static int uda1342_remove(struct i2c_client *client) | |
76 | { | |
77 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | |
78 | ||
79 | v4l2_device_unregister_subdev(sd); | |
73d9f979 HV |
80 | return 0; |
81 | } | |
82 | ||
83 | static const struct i2c_device_id uda1342_id[] = { | |
84 | { "uda1342", 0 }, | |
85 | { } | |
86 | }; | |
87 | MODULE_DEVICE_TABLE(i2c, uda1342_id); | |
88 | ||
89 | static struct i2c_driver uda1342_driver = { | |
90 | .driver = { | |
91 | .name = "uda1342", | |
92 | }, | |
93 | .probe = uda1342_probe, | |
94 | .remove = uda1342_remove, | |
95 | .id_table = uda1342_id, | |
96 | }; | |
97 | ||
98 | module_i2c_driver(uda1342_driver); | |
99 | ||
100 | MODULE_LICENSE("GPL v2"); |