summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel@collabora.com>2019-08-15 12:48:03 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-08-26 09:50:48 -0400
commit02283b98b1ac47659b17d575ea24e2b92ead7ede (patch)
treef8a7a2128a3ba83f66bd442cafc1ec2ca0c74c0b
parent7c795df5f344482c2ab8c52ebc1d94302d2b9082 (diff)
media: v4l2-core: move i2c helpers out of v4l2-common.c
Separate the i2c helpers to v4l2-i2c.c, in order to get rid of the ifdefery. No functional changes intended, this is just a cosmetic change to organize the code better. Given I2C is a tristate symbol, a hidden boolean symbol is introduced, to make the conditional build easier. Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--drivers/media/v4l2-core/Kconfig5
-rw-r--r--drivers/media/v4l2-core/Makefile1
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c145
-rw-r--r--drivers/media/v4l2-core/v4l2-i2c.c147
-rw-r--r--include/media/v4l2-common.h113
5 files changed, 229 insertions, 182 deletions
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 7c5f62f196e5..39e3fb30ba0b 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -11,6 +11,11 @@ config VIDEO_V4L2
11 select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE 11 select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
12 default (I2C || I2C=n) && VIDEO_DEV 12 default (I2C || I2C=n) && VIDEO_DEV
13 13
14config VIDEO_V4L2_I2C
15 bool
16 depends on I2C && VIDEO_V4L2
17 default y
18
14config VIDEO_ADV_DEBUG 19config VIDEO_ADV_DEBUG
15 bool "Enable advanced debug functionality on V4L2 drivers" 20 bool "Enable advanced debug functionality on V4L2 drivers"
16 help 21 help
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 2deeeac6ee76..786bd1ec4d1b 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -12,6 +12,7 @@ videodev-$(CONFIG_COMPAT) += v4l2-compat-ioctl32.o
12videodev-$(CONFIG_TRACEPOINTS) += v4l2-trace.o 12videodev-$(CONFIG_TRACEPOINTS) += v4l2-trace.o
13videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o 13videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o
14videodev-$(CONFIG_SPI) += v4l2-spi.o 14videodev-$(CONFIG_SPI) += v4l2-spi.o
15videodev-$(CONFIG_VIDEO_V4L2_I2C) += v4l2-i2c.o
15 16
16obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o 17obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o
17obj-$(CONFIG_VIDEO_V4L2) += videodev.o 18obj-$(CONFIG_VIDEO_V4L2) += videodev.o
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 8ffa758d9342..62f7aa92ac29 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -40,7 +40,6 @@
40#include <linux/mm.h> 40#include <linux/mm.h>
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/errno.h> 42#include <linux/errno.h>
43#include <linux/i2c.h>
44#include <linux/uaccess.h> 43#include <linux/uaccess.h>
45#include <asm/pgtable.h> 44#include <asm/pgtable.h>
46#include <asm/io.h> 45#include <asm/io.h>
@@ -88,150 +87,6 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 _min, s32 _max, s32 _
88} 87}
89EXPORT_SYMBOL(v4l2_ctrl_query_fill); 88EXPORT_SYMBOL(v4l2_ctrl_query_fill);
90 89
91/* I2C Helper functions */
92
93#if IS_ENABLED(CONFIG_I2C)
94
95void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
96 const char *devname, const char *postfix)
97{
98 if (!devname)
99 devname = client->dev.driver->name;
100 if (!postfix)
101 postfix = "";
102
103 snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
104 i2c_adapter_id(client->adapter), client->addr);
105}
106EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);
107
108void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
109 const struct v4l2_subdev_ops *ops)
110{
111 v4l2_subdev_init(sd, ops);
112 sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
113 /* the owner is the same as the i2c_client's driver owner */
114 sd->owner = client->dev.driver->owner;
115 sd->dev = &client->dev;
116 /* i2c_client and v4l2_subdev point to one another */
117 v4l2_set_subdevdata(sd, client);
118 i2c_set_clientdata(client, sd);
119 v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
120}
121EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
122
123/* Load an i2c sub-device. */
124struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
125 struct i2c_adapter *adapter, struct i2c_board_info *info,
126 const unsigned short *probe_addrs)
127{
128 struct v4l2_subdev *sd = NULL;
129 struct i2c_client *client;
130
131 BUG_ON(!v4l2_dev);
132
133 request_module(I2C_MODULE_PREFIX "%s", info->type);
134
135 /* Create the i2c client */
136 if (info->addr == 0 && probe_addrs)
137 client = i2c_new_probed_device(adapter, info, probe_addrs,
138 NULL);
139 else
140 client = i2c_new_device(adapter, info);
141
142 /* Note: by loading the module first we are certain that c->driver
143 will be set if the driver was found. If the module was not loaded
144 first, then the i2c core tries to delay-load the module for us,
145 and then c->driver is still NULL until the module is finally
146 loaded. This delay-load mechanism doesn't work if other drivers
147 want to use the i2c device, so explicitly loading the module
148 is the best alternative. */
149 if (client == NULL || client->dev.driver == NULL)
150 goto error;
151
152 /* Lock the module so we can safely get the v4l2_subdev pointer */
153 if (!try_module_get(client->dev.driver->owner))
154 goto error;
155 sd = i2c_get_clientdata(client);
156
157 /* Register with the v4l2_device which increases the module's
158 use count as well. */
159 if (v4l2_device_register_subdev(v4l2_dev, sd))
160 sd = NULL;
161 /* Decrease the module use count to match the first try_module_get. */
162 module_put(client->dev.driver->owner);
163
164error:
165 /* If we have a client but no subdev, then something went wrong and
166 we must unregister the client. */
167 if (client && sd == NULL)
168 i2c_unregister_device(client);
169 return sd;
170}
171EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
172
173struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
174 struct i2c_adapter *adapter, const char *client_type,
175 u8 addr, const unsigned short *probe_addrs)
176{
177 struct i2c_board_info info;
178
179 /* Setup the i2c board info with the device type and
180 the device address. */
181 memset(&info, 0, sizeof(info));
182 strscpy(info.type, client_type, sizeof(info.type));
183 info.addr = addr;
184
185 return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
186}
187EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
188
189/* Return i2c client address of v4l2_subdev. */
190unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
191{
192 struct i2c_client *client = v4l2_get_subdevdata(sd);
193
194 return client ? client->addr : I2C_CLIENT_END;
195}
196EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
197
198/* Return a list of I2C tuner addresses to probe. Use only if the tuner
199 addresses are unknown. */
200const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
201{
202 static const unsigned short radio_addrs[] = {
203#if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761)
204 0x10,
205#endif
206 0x60,
207 I2C_CLIENT_END
208 };
209 static const unsigned short demod_addrs[] = {
210 0x42, 0x43, 0x4a, 0x4b,
211 I2C_CLIENT_END
212 };
213 static const unsigned short tv_addrs[] = {
214 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
215 0x60, 0x61, 0x62, 0x63, 0x64,
216 I2C_CLIENT_END
217 };
218
219 switch (type) {
220 case ADDRS_RADIO:
221 return radio_addrs;
222 case ADDRS_DEMOD:
223 return demod_addrs;
224 case ADDRS_TV:
225 return tv_addrs;
226 case ADDRS_TV_WITH_DEMOD:
227 return tv_addrs + 4;
228 }
229 return NULL;
230}
231EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
232
233#endif /* defined(CONFIG_I2C) */
234
235/* Clamp x to be between min and max, aligned to a multiple of 2^align. min 90/* Clamp x to be between min and max, aligned to a multiple of 2^align. min
236 * and max don't have to be aligned, but there must be at least one valid 91 * and max don't have to be aligned, but there must be at least one valid
237 * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples 92 * value. E.g., min=17,max=31,align=4 is not allowed as there are no multiples
diff --git a/drivers/media/v4l2-core/v4l2-i2c.c b/drivers/media/v4l2-core/v4l2-i2c.c
new file mode 100644
index 000000000000..f393dd4f1c00
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-i2c.c
@@ -0,0 +1,147 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * v4l2-i2c - I2C helpers for Video4Linux2
4 */
5
6#include <linux/i2c.h>
7#include <linux/module.h>
8#include <media/v4l2-common.h>
9#include <media/v4l2-device.h>
10
11void v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
12 const char *devname, const char *postfix)
13{
14 if (!devname)
15 devname = client->dev.driver->name;
16 if (!postfix)
17 postfix = "";
18
19 snprintf(sd->name, sizeof(sd->name), "%s%s %d-%04x", devname, postfix,
20 i2c_adapter_id(client->adapter), client->addr);
21}
22EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_set_name);
23
24void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
25 const struct v4l2_subdev_ops *ops)
26{
27 v4l2_subdev_init(sd, ops);
28 sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
29 /* the owner is the same as the i2c_client's driver owner */
30 sd->owner = client->dev.driver->owner;
31 sd->dev = &client->dev;
32 /* i2c_client and v4l2_subdev point to one another */
33 v4l2_set_subdevdata(sd, client);
34 i2c_set_clientdata(client, sd);
35 v4l2_i2c_subdev_set_name(sd, client, NULL, NULL);
36}
37EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
38
39/* Load an i2c sub-device. */
40struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
41 struct i2c_adapter *adapter, struct i2c_board_info *info,
42 const unsigned short *probe_addrs)
43{
44 struct v4l2_subdev *sd = NULL;
45 struct i2c_client *client;
46
47 BUG_ON(!v4l2_dev);
48
49 request_module(I2C_MODULE_PREFIX "%s", info->type);
50
51 /* Create the i2c client */
52 if (info->addr == 0 && probe_addrs)
53 client = i2c_new_probed_device(adapter, info, probe_addrs,
54 NULL);
55 else
56 client = i2c_new_device(adapter, info);
57
58 /* Note: by loading the module first we are certain that c->driver
59 will be set if the driver was found. If the module was not loaded
60 first, then the i2c core tries to delay-load the module for us,
61 and then c->driver is still NULL until the module is finally
62 loaded. This delay-load mechanism doesn't work if other drivers
63 want to use the i2c device, so explicitly loading the module
64 is the best alternative. */
65 if (client == NULL || client->dev.driver == NULL)
66 goto error;
67
68 /* Lock the module so we can safely get the v4l2_subdev pointer */
69 if (!try_module_get(client->dev.driver->owner))
70 goto error;
71 sd = i2c_get_clientdata(client);
72
73 /* Register with the v4l2_device which increases the module's
74 use count as well. */
75 if (v4l2_device_register_subdev(v4l2_dev, sd))
76 sd = NULL;
77 /* Decrease the module use count to match the first try_module_get. */
78 module_put(client->dev.driver->owner);
79
80error:
81 /* If we have a client but no subdev, then something went wrong and
82 we must unregister the client. */
83 if (client && sd == NULL)
84 i2c_unregister_device(client);
85 return sd;
86}
87EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board);
88
89struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
90 struct i2c_adapter *adapter, const char *client_type,
91 u8 addr, const unsigned short *probe_addrs)
92{
93 struct i2c_board_info info;
94
95 /* Setup the i2c board info with the device type and
96 the device address. */
97 memset(&info, 0, sizeof(info));
98 strscpy(info.type, client_type, sizeof(info.type));
99 info.addr = addr;
100
101 return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs);
102}
103EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
104
105/* Return i2c client address of v4l2_subdev. */
106unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
107{
108 struct i2c_client *client = v4l2_get_subdevdata(sd);
109
110 return client ? client->addr : I2C_CLIENT_END;
111}
112EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
113
114/* Return a list of I2C tuner addresses to probe. Use only if the tuner
115 addresses are unknown. */
116const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
117{
118 static const unsigned short radio_addrs[] = {
119#if IS_ENABLED(CONFIG_MEDIA_TUNER_TEA5761)
120 0x10,
121#endif
122 0x60,
123 I2C_CLIENT_END
124 };
125 static const unsigned short demod_addrs[] = {
126 0x42, 0x43, 0x4a, 0x4b,
127 I2C_CLIENT_END
128 };
129 static const unsigned short tv_addrs[] = {
130 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
131 0x60, 0x61, 0x62, 0x63, 0x64,
132 I2C_CLIENT_END
133 };
134
135 switch (type) {
136 case ADDRS_RADIO:
137 return radio_addrs;
138 case ADDRS_DEMOD:
139 return demod_addrs;
140 case ADDRS_TV:
141 return tv_addrs;
142 case ADDRS_TV_WITH_DEMOD:
143 return tv_addrs + 4;
144 }
145 return NULL;
146}
147EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index a1c5288caa6a..8e66edddd37b 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -96,16 +96,45 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
96 96
97/* ------------------------------------------------------------------------- */ 97/* ------------------------------------------------------------------------- */
98 98
99/* I2C Helper functions */
100
101struct i2c_driver;
102struct i2c_adapter;
103struct i2c_client;
104struct i2c_device_id;
105struct v4l2_device; 99struct v4l2_device;
106struct v4l2_subdev; 100struct v4l2_subdev;
107struct v4l2_subdev_ops; 101struct v4l2_subdev_ops;
108 102
103/* I2C Helper functions */
104#include <linux/i2c.h>
105
106/**
107 * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
108 * should be used when seeking for I2C devices.
109 *
110 * @ADDRS_RADIO: Radio tuner addresses.
111 * Represent the following I2C addresses:
112 * 0x10 (if compiled with tea5761 support)
113 * and 0x60.
114 * @ADDRS_DEMOD: Demod tuner addresses.
115 * Represent the following I2C addresses:
116 * 0x42, 0x43, 0x4a and 0x4b.
117 * @ADDRS_TV: TV tuner addresses.
118 * Represent the following I2C addresses:
119 * 0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
120 * 0x63 and 0x64.
121 * @ADDRS_TV_WITH_DEMOD: TV tuner addresses if demod is present, this
122 * excludes addresses used by the demodulator
123 * from the list of candidates.
124 * Represent the following I2C addresses:
125 * 0x60, 0x61, 0x62, 0x63 and 0x64.
126 *
127 * NOTE: All I2C addresses above use the 7-bit notation.
128 */
129enum v4l2_i2c_tuner_type {
130 ADDRS_RADIO,
131 ADDRS_DEMOD,
132 ADDRS_TV,
133 ADDRS_TV_WITH_DEMOD,
134};
135
136#if defined(CONFIG_VIDEO_V4L2_I2C)
137
109/** 138/**
110 * v4l2_i2c_new_subdev - Load an i2c module and return an initialized 139 * v4l2_i2c_new_subdev - Load an i2c module and return an initialized
111 * &struct v4l2_subdev. 140 * &struct v4l2_subdev.
@@ -123,8 +152,6 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
123 struct i2c_adapter *adapter, const char *client_type, 152 struct i2c_adapter *adapter, const char *client_type,
124 u8 addr, const unsigned short *probe_addrs); 153 u8 addr, const unsigned short *probe_addrs);
125 154
126struct i2c_board_info;
127
128/** 155/**
129 * v4l2_i2c_new_subdev_board - Load an i2c module and return an initialized 156 * v4l2_i2c_new_subdev_board - Load an i2c module and return an initialized
130 * &struct v4l2_subdev. 157 * &struct v4l2_subdev.
@@ -175,35 +202,6 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
175unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd); 202unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);
176 203
177/** 204/**
178 * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
179 * should be used when seeking for I2C devices.
180 *
181 * @ADDRS_RADIO: Radio tuner addresses.
182 * Represent the following I2C addresses:
183 * 0x10 (if compiled with tea5761 support)
184 * and 0x60.
185 * @ADDRS_DEMOD: Demod tuner addresses.
186 * Represent the following I2C addresses:
187 * 0x42, 0x43, 0x4a and 0x4b.
188 * @ADDRS_TV: TV tuner addresses.
189 * Represent the following I2C addresses:
190 * 0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
191 * 0x63 and 0x64.
192 * @ADDRS_TV_WITH_DEMOD: TV tuner addresses if demod is present, this
193 * excludes addresses used by the demodulator
194 * from the list of candidates.
195 * Represent the following I2C addresses:
196 * 0x60, 0x61, 0x62, 0x63 and 0x64.
197 *
198 * NOTE: All I2C addresses above use the 7-bit notation.
199 */
200enum v4l2_i2c_tuner_type {
201 ADDRS_RADIO,
202 ADDRS_DEMOD,
203 ADDRS_TV,
204 ADDRS_TV_WITH_DEMOD,
205};
206/**
207 * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe. 205 * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
208 * 206 *
209 * @type: type of the tuner to seek, as defined by 207 * @type: type of the tuner to seek, as defined by
@@ -213,6 +211,47 @@ enum v4l2_i2c_tuner_type {
213 */ 211 */
214const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type); 212const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
215 213
214#else
215
216static inline struct v4l2_subdev *
217v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
218 struct i2c_adapter *adapter, const char *client_type,
219 u8 addr, const unsigned short *probe_addrs)
220{
221 return NULL;
222}
223
224static inline struct v4l2_subdev *
225v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
226 struct i2c_adapter *adapter, struct i2c_board_info *info,
227 const unsigned short *probe_addrs)
228{
229 return NULL;
230}
231
232static inline void
233v4l2_i2c_subdev_set_name(struct v4l2_subdev *sd, struct i2c_client *client,
234 const char *devname, const char *postfix)
235{}
236
237static inline void
238v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
239 const struct v4l2_subdev_ops *ops)
240{}
241
242static inline unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
243{
244 return I2C_CLIENT_END;
245}
246
247static inline const unsigned short *
248v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
249{
250 return NULL;
251}
252
253#endif
254
216/* ------------------------------------------------------------------------- */ 255/* ------------------------------------------------------------------------- */
217 256
218/* SPI Helper functions */ 257/* SPI Helper functions */