upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / media / video / s5p-tv / mixer_drv.c
1 /*
2  * Samsung TV Mixer driver
3  *
4  * Copyright (c) 2010 Samsung Electronics
5  *
6  * Tomasz Stanislawski, t.stanislaws@samsung.com
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundiation. either version 2 of the License,
11  * or (at your option) any later version
12  */
13
14 #include "plat/tv.h"
15 #include "mixer.h"
16 #include "mixer_reg.h"
17
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/io.h>
21 #include <linux/interrupt.h>
22 #include <linux/irq.h>
23 #include <linux/fb.h>
24 #include <linux/delay.h>
25
26 MODULE_AUTHOR("Tomasz Stanislawski, t.stanislaws@samsung.com");
27 MODULE_DESCRIPTION("Samsung MIXER");
28 MODULE_LICENSE("GPL");
29
30 /* --------- DRIVER INITIALIZATION ---------- */
31
32 static struct platform_driver mxr_driver __refdata;
33
34 static int __init mxr_init(void)
35 {
36         int ret;
37         static const char banner[] __initdata = KERN_INFO
38                 "Samsung TV Mixer driver, (c) 2010 Samsung Electronics\n";
39         printk(banner);
40
41         ret = platform_driver_register(&mxr_driver);
42         if (ret != 0) {
43                 printk(KERN_ERR "registration of MIXER driver failed\n");
44                 return -ENXIO;
45         }
46
47         return 0;
48 }
49 late_initcall(mxr_init);
50
51 static void __exit mxr_exit(void)
52 {
53         platform_driver_unregister(&mxr_driver);
54 }
55 module_exit(mxr_exit);
56
57 static int __devinit mxr_acquire_resources(struct mxr_device *mdev,
58         struct platform_device *pdev);
59
60 static void mxr_release_resources(struct mxr_device *mdev);
61
62 static int __devinit mxr_acquire_layers(struct mxr_device *mdev,
63         struct mxr_platform_data *pdata);
64
65 static void mxr_release_layers(struct mxr_device *mxr_dev);
66
67 static int __devinit mxr_probe(struct platform_device *pdev)
68 {
69         struct device *dev = &pdev->dev;
70         struct mxr_platform_data *pdata = dev->platform_data;
71         struct mxr_device *mdev;
72         int ret;
73
74         dev_info(dev, "probe start\n");
75
76         if (pdata->init) {
77                 ret = pdata->init(dev);
78                 if (ret)
79                         goto fail;
80         }
81
82         mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
83         if (!mdev) {
84                 dev_err(dev, "not enough memory.\n");
85                 ret = -ENOMEM;
86                 goto fail_init;
87         }
88
89         /* setup pointer to master device */
90         mdev->dev = dev;
91
92         mutex_init(&mdev->mutex);
93         spin_lock_init(&mdev->reg_slock);
94
95         /* acquire resources: regs, irqs */
96         ret = mxr_acquire_resources(mdev, pdev);
97         if (ret)
98                 goto fail_mem;
99
100         /* configure resources for video output */
101         ret = mxr_acquire_video(mdev, pdata);
102         if (ret)
103                 goto fail_resources;
104
105         /* configure layers */
106         ret = mxr_acquire_layers(mdev, pdata);
107         if (ret)
108                 goto fail_video;
109
110         dev_info(dev, "probe successful\n");
111         return 0;
112
113 fail_video:
114         mxr_release_video(mdev);
115
116 fail_resources:
117         mxr_release_resources(mdev);
118
119 fail_mem:
120         kfree(mdev);
121
122 fail_init:
123         if (pdata->deinit)
124                 pdata->deinit(dev);
125
126 fail:
127         dev_info(dev, "probe failed\n");
128         return ret;
129 }
130
131 static int __devexit mxr_remove(struct platform_device *pdev)
132 {
133         struct device *dev = &pdev->dev;
134         struct mxr_device *mdev = to_mdev(dev);
135         struct mxr_platform_data *pdata = dev->platform_data;
136
137         mxr_release_layers(mdev);
138         mxr_release_video(mdev);
139         mxr_release_resources(mdev);
140
141         kfree(mdev);
142
143         if (pdata->deinit)
144                 pdata->deinit(dev);
145
146         dev_info(dev, "remove sucessful\n");
147         return 0;
148 }
149
150 static struct platform_driver mxr_driver __refdata = {
151         .probe = mxr_probe,
152         .remove = __devexit_p(mxr_remove),
153         .driver = {
154                 .name = MXR_DRIVER_NAME,
155                 .owner = THIS_MODULE,
156         }
157 };
158
159 static int __devinit mxr_acquire_resources(struct mxr_device *mdev,
160         struct platform_device *pdev)
161 {
162         struct device *dev = &pdev->dev;
163         struct resource *res;
164         int ret;
165         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
166         if (res == NULL) {
167                 dev_err(dev, "get memory resource failed.\n");
168                 ret = -ENXIO;
169                 goto fail;
170         }
171
172         mdev->mxr_regs = ioremap(res->start, resource_size(res));
173         if (mdev->mxr_regs == NULL) {
174                 dev_err(dev, "register mapping failed.\n");
175                 ret = -ENXIO;
176                 goto fail;
177         }
178
179         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
180         if (res == NULL) {
181                 dev_err(dev, "get memory resource failed.\n");
182                 ret = -ENXIO;
183                 goto fail_mxr_regs;
184         }
185
186         mdev->vp_regs = ioremap(res->start, resource_size(res));
187         if (mdev->vp_regs == NULL) {
188                 dev_err(dev, "register mapping failed.\n");
189                 ret = -ENXIO;
190                 goto fail_mxr_regs;
191         }
192
193         res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
194         if (res == NULL) {
195                 dev_err(dev, "get interrupt resource failed.\n");
196                 ret = -ENXIO;
197                 goto fail_vp_regs;
198         }
199
200         ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
201         if (ret) {
202                 dev_err(dev, "request interrupt failed.\n");
203                 goto fail_vp_regs;
204         }
205         mdev->irq = res->start;
206         dev_info(dev, "resources acquired\n");
207
208         return 0;
209
210 fail_vp_regs:
211         iounmap(mdev->vp_regs);
212
213 fail_mxr_regs:
214         iounmap(mdev->mxr_regs);
215
216 fail:
217         return ret;
218 }
219
220 static void mxr_release_resources(struct mxr_device *mdev)
221 {
222         free_irq(mdev->irq, mdev);
223         iounmap(mdev->vp_regs);
224         iounmap(mdev->mxr_regs);
225 }
226
227 static int __devinit mxr_acquire_layers(struct mxr_device *mdev,
228         struct mxr_platform_data *pdata)
229 {
230         mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
231         mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
232         mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
233
234         if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
235                 dev_err(mdev->dev, "failed to acquire layers\n");
236                 goto fail;
237         }
238
239         return 0;
240
241 fail:
242         mxr_release_layers(mdev);
243         return -ENODEV;
244 }
245
246 static void mxr_release_layers(struct mxr_device *mdev)
247 {
248         int i;
249         for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
250                 if (mdev->layer[i])
251                         mxr_layer_release(mdev->layer[i]);
252 }
253
254 void mxr_power_get(struct mxr_device *mdev)
255 {
256         struct device *dev = mdev->dev;
257         struct mxr_platform_data *pdata = dev->platform_data;
258
259         mutex_lock(&mdev->mutex);
260         ++mdev->n_power;
261         dev_info(mdev->dev, "%s(%d)\n", __func__, mdev->n_power);
262         if (mdev->n_power == 1) {
263                 /* power on */
264                 dev_info(dev, "pdata->power_setup = %p\n", pdata->power_setup);
265                 if (pdata->power_setup)
266                         pdata->power_setup(dev, 1);
267                 /* apply default configuration */
268                 mxr_reg_reset(mdev);
269                 v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
270         }
271         mutex_unlock(&mdev->mutex);
272 }
273
274 void mxr_power_put(struct mxr_device *mdev)
275 {
276         struct device *dev = mdev->dev;
277         struct mxr_platform_data *pdata = dev->platform_data;
278
279         mutex_lock(&mdev->mutex);
280         --mdev->n_power;
281         dev_info(mdev->dev, "%s(%d)\n", __func__, mdev->n_power);
282         if (mdev->n_power == 0) {
283                 /* __mxr_reg_deinit(mdev); */
284                 if (pdata->power_setup)
285                         pdata->power_setup(dev, 0);
286                 /* power off */
287                 v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
288         }
289         WARN(mdev->n_power < 0, "negative number of power users (%d)\n",
290                 mdev->n_power);
291         mutex_unlock(&mdev->mutex);
292 }
293
294 void mxr_get_mbus_fmt(struct mxr_device *mdev,
295         struct v4l2_mbus_framefmt *mbus_fmt)
296 {
297         struct v4l2_subdev *sd;
298         int ret;
299         mutex_lock(&mdev->mutex);
300         sd = to_outsd(mdev);
301         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
302         WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
303         mutex_unlock(&mdev->mutex);
304 }
305
306 void mxr_streamer_get(struct mxr_device *mdev)
307 {
308         mutex_lock(&mdev->mutex);
309         ++mdev->n_streamer;
310         dev_info(mdev->dev, "%s(%d)\n", __func__, mdev->n_streamer);
311         if (mdev->n_streamer == 1) {
312                 struct v4l2_subdev *sd = to_outsd(mdev);
313                 struct v4l2_mbus_framefmt mbus_fmt;
314                 int ret;
315                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
316                 WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
317                 mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
318                 mxr_reg_streamon(mdev);
319                 ret = v4l2_subdev_call(sd, video, s_stream, 1);
320                 WARN(ret, "starting stream failed for output %s\n", sd->name);
321         }
322         mutex_unlock(&mdev->mutex);
323         mxr_reg_dump(mdev);
324         /* FIXME: what to do when streaming fails? */
325 }
326
327 void mxr_streamer_put(struct mxr_device *mdev)
328 {
329         mutex_lock(&mdev->mutex);
330         --mdev->n_streamer;
331         dev_info(mdev->dev, "%s(%d)\n", __func__, mdev->n_streamer);
332         if (mdev->n_streamer == 0) {
333                 int ret;
334                 struct v4l2_subdev *sd = to_outsd(mdev);
335                 mxr_reg_streamoff(mdev);
336                 ret = v4l2_subdev_call(sd, video, s_stream, 0);
337                 WARN(ret, "stopping stream failed for output %s\n", sd->name);
338         }
339         WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
340                 mdev->n_streamer);
341         mutex_unlock(&mdev->mutex);
342         mxr_reg_dump(mdev);
343 }
344
345 void mxr_output_get(struct mxr_device *mdev)
346 {
347         mutex_lock(&mdev->mutex);
348         ++mdev->n_output;
349         dev_info(mdev->dev, "%s(%d)\n", __func__, mdev->n_output);
350         mutex_unlock(&mdev->mutex);
351 }
352
353 void mxr_output_put(struct mxr_device *mdev)
354 {
355         mutex_lock(&mdev->mutex);
356         --mdev->n_output;
357         dev_info(mdev->dev, "%s(%d)\n", __func__, mdev->n_output);
358         WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
359                 mdev->n_output);
360         mutex_unlock(&mdev->mutex);
361 }
362