Merge tag 'sound-3.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[firefly-linux-kernel-4.4.55.git] / drivers / media / platform / s5p-tv / mixer_drv.c
1 /*
2  * Samsung TV Mixer driver
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
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 "mixer.h"
15
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/io.h>
19 #include <linux/interrupt.h>
20 #include <linux/irq.h>
21 #include <linux/fb.h>
22 #include <linux/delay.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/clk.h>
25
26 MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
27 MODULE_DESCRIPTION("Samsung MIXER");
28 MODULE_LICENSE("GPL");
29
30 /* --------- DRIVER PARAMETERS ---------- */
31
32 static struct mxr_output_conf mxr_output_conf[] = {
33         {
34                 .output_name = "S5P HDMI connector",
35                 .module_name = "s5p-hdmi",
36                 .cookie = 1,
37         },
38         {
39                 .output_name = "S5P SDO connector",
40                 .module_name = "s5p-sdo",
41                 .cookie = 0,
42         },
43 };
44
45 void mxr_get_mbus_fmt(struct mxr_device *mdev,
46         struct v4l2_mbus_framefmt *mbus_fmt)
47 {
48         struct v4l2_subdev *sd;
49         int ret;
50
51         mutex_lock(&mdev->mutex);
52         sd = to_outsd(mdev);
53         ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
54         WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
55         mutex_unlock(&mdev->mutex);
56 }
57
58 void mxr_streamer_get(struct mxr_device *mdev)
59 {
60         mutex_lock(&mdev->mutex);
61         ++mdev->n_streamer;
62         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
63         if (mdev->n_streamer == 1) {
64                 struct v4l2_subdev *sd = to_outsd(mdev);
65                 struct v4l2_mbus_framefmt mbus_fmt;
66                 struct mxr_resources *res = &mdev->res;
67                 int ret;
68
69                 if (to_output(mdev)->cookie == 0)
70                         clk_set_parent(res->sclk_mixer, res->sclk_dac);
71                 else
72                         clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
73                 mxr_reg_s_output(mdev, to_output(mdev)->cookie);
74
75                 ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
76                 WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
77                 ret = v4l2_subdev_call(sd, video, s_stream, 1);
78                 WARN(ret, "starting stream failed for output %s\n", sd->name);
79
80                 mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
81                 mxr_reg_streamon(mdev);
82                 ret = mxr_reg_wait4vsync(mdev);
83                 WARN(ret, "failed to get vsync (%d) from output\n", ret);
84         }
85         mutex_unlock(&mdev->mutex);
86         mxr_reg_dump(mdev);
87         /* FIXME: what to do when streaming fails? */
88 }
89
90 void mxr_streamer_put(struct mxr_device *mdev)
91 {
92         mutex_lock(&mdev->mutex);
93         --mdev->n_streamer;
94         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
95         if (mdev->n_streamer == 0) {
96                 int ret;
97                 struct v4l2_subdev *sd = to_outsd(mdev);
98
99                 mxr_reg_streamoff(mdev);
100                 /* vsync applies Mixer setup */
101                 ret = mxr_reg_wait4vsync(mdev);
102                 WARN(ret, "failed to get vsync (%d) from output\n", ret);
103                 ret = v4l2_subdev_call(sd, video, s_stream, 0);
104                 WARN(ret, "stopping stream failed for output %s\n", sd->name);
105         }
106         WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
107                 mdev->n_streamer);
108         mutex_unlock(&mdev->mutex);
109         mxr_reg_dump(mdev);
110 }
111
112 void mxr_output_get(struct mxr_device *mdev)
113 {
114         mutex_lock(&mdev->mutex);
115         ++mdev->n_output;
116         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
117         /* turn on auxiliary driver */
118         if (mdev->n_output == 1)
119                 v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
120         mutex_unlock(&mdev->mutex);
121 }
122
123 void mxr_output_put(struct mxr_device *mdev)
124 {
125         mutex_lock(&mdev->mutex);
126         --mdev->n_output;
127         mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
128         /* turn on auxiliary driver */
129         if (mdev->n_output == 0)
130                 v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
131         WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
132                 mdev->n_output);
133         mutex_unlock(&mdev->mutex);
134 }
135
136 int mxr_power_get(struct mxr_device *mdev)
137 {
138         int ret = pm_runtime_get_sync(mdev->dev);
139
140         /* returning 1 means that power is already enabled,
141          * so zero success be returned */
142         if (IS_ERR_VALUE(ret))
143                 return ret;
144         return 0;
145 }
146
147 void mxr_power_put(struct mxr_device *mdev)
148 {
149         pm_runtime_put_sync(mdev->dev);
150 }
151
152 /* --------- RESOURCE MANAGEMENT -------------*/
153
154 static int mxr_acquire_plat_resources(struct mxr_device *mdev,
155                                       struct platform_device *pdev)
156 {
157         struct resource *res;
158         int ret;
159
160         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
161         if (res == NULL) {
162                 mxr_err(mdev, "get memory resource failed.\n");
163                 ret = -ENXIO;
164                 goto fail;
165         }
166
167         mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
168         if (mdev->res.mxr_regs == NULL) {
169                 mxr_err(mdev, "register mapping failed.\n");
170                 ret = -ENXIO;
171                 goto fail;
172         }
173
174         res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
175         if (res == NULL) {
176                 mxr_err(mdev, "get memory resource failed.\n");
177                 ret = -ENXIO;
178                 goto fail_mxr_regs;
179         }
180
181         mdev->res.vp_regs = ioremap(res->start, resource_size(res));
182         if (mdev->res.vp_regs == NULL) {
183                 mxr_err(mdev, "register mapping failed.\n");
184                 ret = -ENXIO;
185                 goto fail_mxr_regs;
186         }
187
188         res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
189         if (res == NULL) {
190                 mxr_err(mdev, "get interrupt resource failed.\n");
191                 ret = -ENXIO;
192                 goto fail_vp_regs;
193         }
194
195         ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
196         if (ret) {
197                 mxr_err(mdev, "request interrupt failed.\n");
198                 goto fail_vp_regs;
199         }
200         mdev->res.irq = res->start;
201
202         return 0;
203
204 fail_vp_regs:
205         iounmap(mdev->res.vp_regs);
206
207 fail_mxr_regs:
208         iounmap(mdev->res.mxr_regs);
209
210 fail:
211         return ret;
212 }
213
214 static void mxr_resource_clear_clocks(struct mxr_resources *res)
215 {
216         res->mixer      = ERR_PTR(-EINVAL);
217         res->vp         = ERR_PTR(-EINVAL);
218         res->sclk_mixer = ERR_PTR(-EINVAL);
219         res->sclk_hdmi  = ERR_PTR(-EINVAL);
220         res->sclk_dac   = ERR_PTR(-EINVAL);
221 }
222
223 static void mxr_release_plat_resources(struct mxr_device *mdev)
224 {
225         free_irq(mdev->res.irq, mdev);
226         iounmap(mdev->res.vp_regs);
227         iounmap(mdev->res.mxr_regs);
228 }
229
230 static void mxr_release_clocks(struct mxr_device *mdev)
231 {
232         struct mxr_resources *res = &mdev->res;
233
234         if (!IS_ERR(res->sclk_dac))
235                 clk_put(res->sclk_dac);
236         if (!IS_ERR(res->sclk_hdmi))
237                 clk_put(res->sclk_hdmi);
238         if (!IS_ERR(res->sclk_mixer))
239                 clk_put(res->sclk_mixer);
240         if (!IS_ERR(res->vp))
241                 clk_put(res->vp);
242         if (!IS_ERR(res->mixer))
243                 clk_put(res->mixer);
244 }
245
246 static int mxr_acquire_clocks(struct mxr_device *mdev)
247 {
248         struct mxr_resources *res = &mdev->res;
249         struct device *dev = mdev->dev;
250
251         mxr_resource_clear_clocks(res);
252
253         res->mixer = clk_get(dev, "mixer");
254         if (IS_ERR(res->mixer)) {
255                 mxr_err(mdev, "failed to get clock 'mixer'\n");
256                 goto fail;
257         }
258         res->vp = clk_get(dev, "vp");
259         if (IS_ERR(res->vp)) {
260                 mxr_err(mdev, "failed to get clock 'vp'\n");
261                 goto fail;
262         }
263         res->sclk_mixer = clk_get(dev, "sclk_mixer");
264         if (IS_ERR(res->sclk_mixer)) {
265                 mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
266                 goto fail;
267         }
268         res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
269         if (IS_ERR(res->sclk_hdmi)) {
270                 mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
271                 goto fail;
272         }
273         res->sclk_dac = clk_get(dev, "sclk_dac");
274         if (IS_ERR(res->sclk_dac)) {
275                 mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
276                 goto fail;
277         }
278
279         return 0;
280 fail:
281         mxr_release_clocks(mdev);
282         return -ENODEV;
283 }
284
285 static int mxr_acquire_resources(struct mxr_device *mdev,
286                                  struct platform_device *pdev)
287 {
288         int ret;
289         ret = mxr_acquire_plat_resources(mdev, pdev);
290
291         if (ret)
292                 goto fail;
293
294         ret = mxr_acquire_clocks(mdev);
295         if (ret)
296                 goto fail_plat;
297
298         mxr_info(mdev, "resources acquired\n");
299         return 0;
300
301 fail_plat:
302         mxr_release_plat_resources(mdev);
303 fail:
304         mxr_err(mdev, "resources acquire failed\n");
305         return ret;
306 }
307
308 static void mxr_release_resources(struct mxr_device *mdev)
309 {
310         mxr_release_clocks(mdev);
311         mxr_release_plat_resources(mdev);
312         memset(&mdev->res, 0, sizeof(mdev->res));
313         mxr_resource_clear_clocks(&mdev->res);
314 }
315
316 static void mxr_release_layers(struct mxr_device *mdev)
317 {
318         int i;
319
320         for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
321                 if (mdev->layer[i])
322                         mxr_layer_release(mdev->layer[i]);
323 }
324
325 static int mxr_acquire_layers(struct mxr_device *mdev,
326                               struct mxr_platform_data *pdata)
327 {
328         mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
329         mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
330         mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
331
332         if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
333                 mxr_err(mdev, "failed to acquire layers\n");
334                 goto fail;
335         }
336
337         return 0;
338
339 fail:
340         mxr_release_layers(mdev);
341         return -ENODEV;
342 }
343
344 /* ---------- POWER MANAGEMENT ----------- */
345
346 static int mxr_runtime_resume(struct device *dev)
347 {
348         struct mxr_device *mdev = to_mdev(dev);
349         struct mxr_resources *res = &mdev->res;
350
351         mxr_dbg(mdev, "resume - start\n");
352         mutex_lock(&mdev->mutex);
353         /* turn clocks on */
354         clk_enable(res->mixer);
355         clk_enable(res->vp);
356         clk_enable(res->sclk_mixer);
357         /* apply default configuration */
358         mxr_reg_reset(mdev);
359         mxr_dbg(mdev, "resume - finished\n");
360
361         mutex_unlock(&mdev->mutex);
362         return 0;
363 }
364
365 static int mxr_runtime_suspend(struct device *dev)
366 {
367         struct mxr_device *mdev = to_mdev(dev);
368         struct mxr_resources *res = &mdev->res;
369         mxr_dbg(mdev, "suspend - start\n");
370         mutex_lock(&mdev->mutex);
371         /* turn clocks off */
372         clk_disable(res->sclk_mixer);
373         clk_disable(res->vp);
374         clk_disable(res->mixer);
375         mutex_unlock(&mdev->mutex);
376         mxr_dbg(mdev, "suspend - finished\n");
377         return 0;
378 }
379
380 static const struct dev_pm_ops mxr_pm_ops = {
381         .runtime_suspend = mxr_runtime_suspend,
382         .runtime_resume  = mxr_runtime_resume,
383 };
384
385 /* --------- DRIVER INITIALIZATION ---------- */
386
387 static int mxr_probe(struct platform_device *pdev)
388 {
389         struct device *dev = &pdev->dev;
390         struct mxr_platform_data *pdata = dev->platform_data;
391         struct mxr_device *mdev;
392         int ret;
393
394         /* mdev does not exist yet so no mxr_dbg is used */
395         dev_info(dev, "probe start\n");
396
397         mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
398         if (!mdev) {
399                 dev_err(dev, "not enough memory.\n");
400                 ret = -ENOMEM;
401                 goto fail;
402         }
403
404         /* setup pointer to master device */
405         mdev->dev = dev;
406
407         mutex_init(&mdev->mutex);
408         spin_lock_init(&mdev->reg_slock);
409         init_waitqueue_head(&mdev->event_queue);
410
411         /* acquire resources: regs, irqs, clocks, regulators */
412         ret = mxr_acquire_resources(mdev, pdev);
413         if (ret)
414                 goto fail_mem;
415
416         /* configure resources for video output */
417         ret = mxr_acquire_video(mdev, mxr_output_conf,
418                 ARRAY_SIZE(mxr_output_conf));
419         if (ret)
420                 goto fail_resources;
421
422         /* configure layers */
423         ret = mxr_acquire_layers(mdev, pdata);
424         if (ret)
425                 goto fail_video;
426
427         pm_runtime_enable(dev);
428
429         mxr_info(mdev, "probe successful\n");
430         return 0;
431
432 fail_video:
433         mxr_release_video(mdev);
434
435 fail_resources:
436         mxr_release_resources(mdev);
437
438 fail_mem:
439         kfree(mdev);
440
441 fail:
442         dev_info(dev, "probe failed\n");
443         return ret;
444 }
445
446 static int mxr_remove(struct platform_device *pdev)
447 {
448         struct device *dev = &pdev->dev;
449         struct mxr_device *mdev = to_mdev(dev);
450
451         pm_runtime_disable(dev);
452
453         mxr_release_layers(mdev);
454         mxr_release_video(mdev);
455         mxr_release_resources(mdev);
456
457         kfree(mdev);
458
459         dev_info(dev, "remove successful\n");
460         return 0;
461 }
462
463 static struct platform_driver mxr_driver __refdata = {
464         .probe = mxr_probe,
465         .remove = mxr_remove,
466         .driver = {
467                 .name = MXR_DRIVER_NAME,
468                 .owner = THIS_MODULE,
469                 .pm = &mxr_pm_ops,
470         }
471 };
472
473 static int __init mxr_init(void)
474 {
475         int i, ret;
476         static const char banner[] __initconst =
477                 "Samsung TV Mixer driver, "
478                 "(c) 2010-2011 Samsung Electronics Co., Ltd.\n";
479         pr_info("%s\n", banner);
480
481         /* Loading auxiliary modules */
482         for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
483                 request_module(mxr_output_conf[i].module_name);
484
485         ret = platform_driver_register(&mxr_driver);
486         if (ret != 0) {
487                 pr_err("s5p-tv: registration of MIXER driver failed\n");
488                 return -ENXIO;
489         }
490
491         return 0;
492 }
493 module_init(mxr_init);
494
495 static void __exit mxr_exit(void)
496 {
497         platform_driver_unregister(&mxr_driver);
498 }
499 module_exit(mxr_exit);