diff options
-rw-r--r-- | drivers/media/video/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/video/soc_mediabus.c | 157 | ||||
-rw-r--r-- | include/media/soc_mediabus.h | 65 | ||||
-rw-r--r-- | include/media/v4l2-mediabus.h | 61 | ||||
-rw-r--r-- | include/media/v4l2-subdev.h | 18 |
5 files changed, 301 insertions, 2 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 7a2dcc34111c..e7bc8daae064 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -149,7 +149,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o | |||
149 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ | 149 | obj-$(CONFIG_VIDEO_CX23885) += cx23885/ |
150 | 150 | ||
151 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o | 151 | obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o |
152 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o | 152 | obj-$(CONFIG_SOC_CAMERA) += soc_camera.o soc_mediabus.o |
153 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o | 153 | obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o |
154 | # soc-camera host drivers have to be linked after camera drivers | 154 | # soc-camera host drivers have to be linked after camera drivers |
155 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o | 155 | obj-$(CONFIG_VIDEO_MX1) += mx1_camera.o |
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c new file mode 100644 index 000000000000..f8d5c87dc2aa --- /dev/null +++ b/drivers/media/video/soc_mediabus.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | * soc-camera media bus helper routines | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | |||
14 | #include <media/v4l2-device.h> | ||
15 | #include <media/v4l2-mediabus.h> | ||
16 | #include <media/soc_mediabus.h> | ||
17 | |||
18 | #define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1) | ||
19 | |||
20 | static const struct soc_mbus_pixelfmt mbus_fmt[] = { | ||
21 | [MBUS_IDX(YUYV8_2X8_LE)] = { | ||
22 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
23 | .name = "YUYV", | ||
24 | .bits_per_sample = 8, | ||
25 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
26 | .order = SOC_MBUS_ORDER_LE, | ||
27 | }, [MBUS_IDX(YVYU8_2X8_LE)] = { | ||
28 | .fourcc = V4L2_PIX_FMT_YVYU, | ||
29 | .name = "YVYU", | ||
30 | .bits_per_sample = 8, | ||
31 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
32 | .order = SOC_MBUS_ORDER_LE, | ||
33 | }, [MBUS_IDX(YUYV8_2X8_BE)] = { | ||
34 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
35 | .name = "UYVY", | ||
36 | .bits_per_sample = 8, | ||
37 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
38 | .order = SOC_MBUS_ORDER_LE, | ||
39 | }, [MBUS_IDX(YVYU8_2X8_BE)] = { | ||
40 | .fourcc = V4L2_PIX_FMT_VYUY, | ||
41 | .name = "VYUY", | ||
42 | .bits_per_sample = 8, | ||
43 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
44 | .order = SOC_MBUS_ORDER_LE, | ||
45 | }, [MBUS_IDX(RGB555_2X8_PADHI_LE)] = { | ||
46 | .fourcc = V4L2_PIX_FMT_RGB555, | ||
47 | .name = "RGB555", | ||
48 | .bits_per_sample = 8, | ||
49 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
50 | .order = SOC_MBUS_ORDER_LE, | ||
51 | }, [MBUS_IDX(RGB555_2X8_PADHI_BE)] = { | ||
52 | .fourcc = V4L2_PIX_FMT_RGB555X, | ||
53 | .name = "RGB555X", | ||
54 | .bits_per_sample = 8, | ||
55 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
56 | .order = SOC_MBUS_ORDER_LE, | ||
57 | }, [MBUS_IDX(RGB565_2X8_LE)] = { | ||
58 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
59 | .name = "RGB565", | ||
60 | .bits_per_sample = 8, | ||
61 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
62 | .order = SOC_MBUS_ORDER_LE, | ||
63 | }, [MBUS_IDX(RGB565_2X8_BE)] = { | ||
64 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
65 | .name = "RGB565X", | ||
66 | .bits_per_sample = 8, | ||
67 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
68 | .order = SOC_MBUS_ORDER_LE, | ||
69 | }, [MBUS_IDX(SBGGR8_1X8)] = { | ||
70 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
71 | .name = "Bayer 8 BGGR", | ||
72 | .bits_per_sample = 8, | ||
73 | .packing = SOC_MBUS_PACKING_NONE, | ||
74 | .order = SOC_MBUS_ORDER_LE, | ||
75 | }, [MBUS_IDX(SBGGR10_1X10)] = { | ||
76 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
77 | .name = "Bayer 10 BGGR", | ||
78 | .bits_per_sample = 10, | ||
79 | .packing = SOC_MBUS_PACKING_EXTEND16, | ||
80 | .order = SOC_MBUS_ORDER_LE, | ||
81 | }, [MBUS_IDX(GREY8_1X8)] = { | ||
82 | .fourcc = V4L2_PIX_FMT_GREY, | ||
83 | .name = "Grey", | ||
84 | .bits_per_sample = 8, | ||
85 | .packing = SOC_MBUS_PACKING_NONE, | ||
86 | .order = SOC_MBUS_ORDER_LE, | ||
87 | }, [MBUS_IDX(Y10_1X10)] = { | ||
88 | .fourcc = V4L2_PIX_FMT_Y10, | ||
89 | .name = "Grey 10bit", | ||
90 | .bits_per_sample = 10, | ||
91 | .packing = SOC_MBUS_PACKING_EXTEND16, | ||
92 | .order = SOC_MBUS_ORDER_LE, | ||
93 | }, [MBUS_IDX(SBGGR10_2X8_PADHI_LE)] = { | ||
94 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
95 | .name = "Bayer 10 BGGR", | ||
96 | .bits_per_sample = 8, | ||
97 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
98 | .order = SOC_MBUS_ORDER_LE, | ||
99 | }, [MBUS_IDX(SBGGR10_2X8_PADLO_LE)] = { | ||
100 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
101 | .name = "Bayer 10 BGGR", | ||
102 | .bits_per_sample = 8, | ||
103 | .packing = SOC_MBUS_PACKING_2X8_PADLO, | ||
104 | .order = SOC_MBUS_ORDER_LE, | ||
105 | }, [MBUS_IDX(SBGGR10_2X8_PADHI_BE)] = { | ||
106 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
107 | .name = "Bayer 10 BGGR", | ||
108 | .bits_per_sample = 8, | ||
109 | .packing = SOC_MBUS_PACKING_2X8_PADHI, | ||
110 | .order = SOC_MBUS_ORDER_BE, | ||
111 | }, [MBUS_IDX(SBGGR10_2X8_PADLO_BE)] = { | ||
112 | .fourcc = V4L2_PIX_FMT_SBGGR10, | ||
113 | .name = "Bayer 10 BGGR", | ||
114 | .bits_per_sample = 8, | ||
115 | .packing = SOC_MBUS_PACKING_2X8_PADLO, | ||
116 | .order = SOC_MBUS_ORDER_BE, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) | ||
121 | { | ||
122 | switch (mf->packing) { | ||
123 | case SOC_MBUS_PACKING_NONE: | ||
124 | return width * mf->bits_per_sample / 8; | ||
125 | case SOC_MBUS_PACKING_2X8_PADHI: | ||
126 | case SOC_MBUS_PACKING_2X8_PADLO: | ||
127 | case SOC_MBUS_PACKING_EXTEND16: | ||
128 | return width * 2; | ||
129 | } | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | EXPORT_SYMBOL(soc_mbus_bytes_per_line); | ||
133 | |||
134 | const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( | ||
135 | enum v4l2_mbus_pixelcode code) | ||
136 | { | ||
137 | if ((unsigned int)(code - V4L2_MBUS_FMT_FIXED) > ARRAY_SIZE(mbus_fmt)) | ||
138 | return NULL; | ||
139 | return mbus_fmt + code - V4L2_MBUS_FMT_FIXED - 1; | ||
140 | } | ||
141 | EXPORT_SYMBOL(soc_mbus_get_fmtdesc); | ||
142 | |||
143 | static int __init soc_mbus_init(void) | ||
144 | { | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void __exit soc_mbus_exit(void) | ||
149 | { | ||
150 | } | ||
151 | |||
152 | module_init(soc_mbus_init); | ||
153 | module_exit(soc_mbus_exit); | ||
154 | |||
155 | MODULE_DESCRIPTION("soc-camera media bus interface"); | ||
156 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
157 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h new file mode 100644 index 000000000000..037cd7be001e --- /dev/null +++ b/include/media/soc_mediabus.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * SoC-camera Media Bus API extensions | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef SOC_MEDIABUS_H | ||
12 | #define SOC_MEDIABUS_H | ||
13 | |||
14 | #include <linux/videodev2.h> | ||
15 | |||
16 | #include <media/v4l2-mediabus.h> | ||
17 | |||
18 | /** | ||
19 | * enum soc_mbus_packing - data packing types on the media-bus | ||
20 | * @SOC_MBUS_PACKING_NONE: no packing, bit-for-bit transfer to RAM | ||
21 | * @SOC_MBUS_PACKING_2X8_PADHI: 16 bits transferred in 2 8-bit samples, in the | ||
22 | * possibly incomplete byte high bits are padding | ||
23 | * @SOC_MBUS_PACKING_2X8_PADLO: as above, but low bits are padding | ||
24 | * @SOC_MBUS_PACKING_EXTEND16: sample width (e.g., 10 bits) has to be extended | ||
25 | * to 16 bits | ||
26 | */ | ||
27 | enum soc_mbus_packing { | ||
28 | SOC_MBUS_PACKING_NONE, | ||
29 | SOC_MBUS_PACKING_2X8_PADHI, | ||
30 | SOC_MBUS_PACKING_2X8_PADLO, | ||
31 | SOC_MBUS_PACKING_EXTEND16, | ||
32 | }; | ||
33 | |||
34 | /** | ||
35 | * enum soc_mbus_order - sample order on the media bus | ||
36 | * @SOC_MBUS_ORDER_LE: least significant sample first | ||
37 | * @SOC_MBUS_ORDER_BE: most significant sample first | ||
38 | */ | ||
39 | enum soc_mbus_order { | ||
40 | SOC_MBUS_ORDER_LE, | ||
41 | SOC_MBUS_ORDER_BE, | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * struct soc_mbus_pixelfmt - Data format on the media bus | ||
46 | * @name: Name of the format | ||
47 | * @fourcc: Fourcc code, that will be obtained if the data is | ||
48 | * stored in memory in the following way: | ||
49 | * @packing: Type of sample-packing, that has to be used | ||
50 | * @order: Sample order when storing in memory | ||
51 | * @bits_per_sample: How many bits the bridge has to sample | ||
52 | */ | ||
53 | struct soc_mbus_pixelfmt { | ||
54 | const char *name; | ||
55 | u32 fourcc; | ||
56 | enum soc_mbus_packing packing; | ||
57 | enum soc_mbus_order order; | ||
58 | u8 bits_per_sample; | ||
59 | }; | ||
60 | |||
61 | const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( | ||
62 | enum v4l2_mbus_pixelcode code); | ||
63 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); | ||
64 | |||
65 | #endif | ||
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h new file mode 100644 index 000000000000..0dbe02ada259 --- /dev/null +++ b/include/media/v4l2-mediabus.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Media Bus API header | ||
3 | * | ||
4 | * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef V4L2_MEDIABUS_H | ||
12 | #define V4L2_MEDIABUS_H | ||
13 | |||
14 | /* | ||
15 | * These pixel codes uniquely identify data formats on the media bus. Mostly | ||
16 | * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is | ||
17 | * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the | ||
18 | * data format is fixed. Additionally, "2X8" means that one pixel is transferred | ||
19 | * in two 8-bit samples, "BE" or "LE" specify in which order those samples are | ||
20 | * transferred over the bus: "LE" means that the least significant bits are | ||
21 | * transferred first, "BE" means that the most significant bits are transferred | ||
22 | * first, and "PADHI" and "PADLO" define which bits - low or high, in the | ||
23 | * incomplete high byte, are filled with padding bits. | ||
24 | */ | ||
25 | enum v4l2_mbus_pixelcode { | ||
26 | V4L2_MBUS_FMT_FIXED = 1, | ||
27 | V4L2_MBUS_FMT_YUYV8_2X8_LE, | ||
28 | V4L2_MBUS_FMT_YVYU8_2X8_LE, | ||
29 | V4L2_MBUS_FMT_YUYV8_2X8_BE, | ||
30 | V4L2_MBUS_FMT_YVYU8_2X8_BE, | ||
31 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, | ||
32 | V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, | ||
33 | V4L2_MBUS_FMT_RGB565_2X8_LE, | ||
34 | V4L2_MBUS_FMT_RGB565_2X8_BE, | ||
35 | V4L2_MBUS_FMT_SBGGR8_1X8, | ||
36 | V4L2_MBUS_FMT_SBGGR10_1X10, | ||
37 | V4L2_MBUS_FMT_GREY8_1X8, | ||
38 | V4L2_MBUS_FMT_Y10_1X10, | ||
39 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE, | ||
40 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE, | ||
41 | V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, | ||
42 | V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, | ||
43 | }; | ||
44 | |||
45 | /** | ||
46 | * struct v4l2_mbus_framefmt - frame format on the media bus | ||
47 | * @width: frame width | ||
48 | * @height: frame height | ||
49 | * @code: data format code | ||
50 | * @field: used interlacing type | ||
51 | * @colorspace: colorspace of the data | ||
52 | */ | ||
53 | struct v4l2_mbus_framefmt { | ||
54 | __u32 width; | ||
55 | __u32 height; | ||
56 | enum v4l2_mbus_pixelcode code; | ||
57 | enum v4l2_field field; | ||
58 | enum v4l2_colorspace colorspace; | ||
59 | }; | ||
60 | |||
61 | #endif | ||
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index a128458dc9eb..9ba99cd39ee7 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define _V4L2_SUBDEV_H | 22 | #define _V4L2_SUBDEV_H |
23 | 23 | ||
24 | #include <media/v4l2-common.h> | 24 | #include <media/v4l2-common.h> |
25 | #include <media/v4l2-mediabus.h> | ||
25 | 26 | ||
26 | /* generic v4l2_device notify callback notification values */ | 27 | /* generic v4l2_device notify callback notification values */ |
27 | #define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) | 28 | #define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) |
@@ -207,7 +208,7 @@ struct v4l2_subdev_audio_ops { | |||
207 | s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by | 208 | s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by |
208 | video input devices. | 209 | video input devices. |
209 | 210 | ||
210 | s_crystal_freq: sets the frequency of the crystal used to generate the | 211 | s_crystal_freq: sets the frequency of the crystal used to generate the |
211 | clocks in Hz. An extra flags field allows device specific configuration | 212 | clocks in Hz. An extra flags field allows device specific configuration |
212 | regarding clock frequency dividers, etc. If not used, then set flags | 213 | regarding clock frequency dividers, etc. If not used, then set flags |
213 | to 0. If the frequency is not supported, then -EINVAL is returned. | 214 | to 0. If the frequency is not supported, then -EINVAL is returned. |
@@ -230,6 +231,13 @@ struct v4l2_subdev_audio_ops { | |||
230 | 231 | ||
231 | g_dv_timings(): Get custom dv timings in the sub device. | 232 | g_dv_timings(): Get custom dv timings in the sub device. |
232 | 233 | ||
234 | enum_mbus_fmt: enumerate pixel formats, provided by a video data source | ||
235 | |||
236 | g_mbus_fmt: get the current pixel format, provided by a video data source | ||
237 | |||
238 | try_mbus_fmt: try to set a pixel format on a video data source | ||
239 | |||
240 | s_mbus_fmt: set a pixel format on a video data source | ||
233 | */ | 241 | */ |
234 | struct v4l2_subdev_video_ops { | 242 | struct v4l2_subdev_video_ops { |
235 | int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); | 243 | int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); |
@@ -261,6 +269,14 @@ struct v4l2_subdev_video_ops { | |||
261 | struct v4l2_dv_timings *timings); | 269 | struct v4l2_dv_timings *timings); |
262 | int (*g_dv_timings)(struct v4l2_subdev *sd, | 270 | int (*g_dv_timings)(struct v4l2_subdev *sd, |
263 | struct v4l2_dv_timings *timings); | 271 | struct v4l2_dv_timings *timings); |
272 | int (*enum_mbus_fmt)(struct v4l2_subdev *sd, int index, | ||
273 | enum v4l2_mbus_pixelcode *code); | ||
274 | int (*g_mbus_fmt)(struct v4l2_subdev *sd, | ||
275 | struct v4l2_mbus_framefmt *fmt); | ||
276 | int (*try_mbus_fmt)(struct v4l2_subdev *sd, | ||
277 | struct v4l2_mbus_framefmt *fmt); | ||
278 | int (*s_mbus_fmt)(struct v4l2_subdev *sd, | ||
279 | struct v4l2_mbus_framefmt *fmt); | ||
264 | }; | 280 | }; |
265 | 281 | ||
266 | /** | 282 | /** |