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