1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2005-2006 Micronas USA Inc. |
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> |
11 | #include <media/i2c/uda1342.h> |
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, command: 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, reg: 0x00, value: 0x1241); /* select input 1 */ |
29 | break; |
30 | case UDA1342_IN2: |
31 | write_reg(client, reg: 0x00, value: 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 | { |
50 | struct i2c_adapter *adapter = client->adapter; |
51 | struct v4l2_subdev *sd; |
52 | |
53 | if (!i2c_check_functionality(adap: adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
54 | return -ENODEV; |
55 | |
56 | dev_dbg(&client->dev, "initializing UDA1342 at address %d on %s\n" , |
57 | client->addr, adapter->name); |
58 | |
59 | sd = devm_kzalloc(dev: &client->dev, size: sizeof(*sd), GFP_KERNEL); |
60 | if (sd == NULL) |
61 | return -ENOMEM; |
62 | |
63 | v4l2_i2c_subdev_init(sd, client, ops: &uda1342_ops); |
64 | |
65 | write_reg(client, reg: 0x00, value: 0x8000); /* reset registers */ |
66 | write_reg(client, reg: 0x00, value: 0x1241); /* select input 1 */ |
67 | |
68 | v4l_info(client, "chip found @ 0x%02x (%s)\n" , |
69 | client->addr << 1, client->adapter->name); |
70 | |
71 | return 0; |
72 | } |
73 | |
74 | static void uda1342_remove(struct i2c_client *client) |
75 | { |
76 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
77 | |
78 | v4l2_device_unregister_subdev(sd); |
79 | } |
80 | |
81 | static const struct i2c_device_id uda1342_id[] = { |
82 | { "uda1342" , 0 }, |
83 | { } |
84 | }; |
85 | MODULE_DEVICE_TABLE(i2c, uda1342_id); |
86 | |
87 | static struct i2c_driver uda1342_driver = { |
88 | .driver = { |
89 | .name = "uda1342" , |
90 | }, |
91 | .probe = uda1342_probe, |
92 | .remove = uda1342_remove, |
93 | .id_table = uda1342_id, |
94 | }; |
95 | |
96 | module_i2c_driver(uda1342_driver); |
97 | |
98 | MODULE_LICENSE("GPL v2" ); |
99 | |