cregit-Linux how code gets into the kernel

Release 4.7 drivers/media/platform/s5p-tv/mixer_drv.c

/*
 * Samsung TV Mixer driver
 *
 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
 *
 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundiation. either version 2 of the License,
 * or (at your option) any later version
 */

#include "mixer.h"

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>

MODULE_AUTHOR("Tomasz Stanislawski, <t.stanislaws@samsung.com>");
MODULE_DESCRIPTION("Samsung MIXER");
MODULE_LICENSE("GPL");

/* --------- DRIVER PARAMETERS ---------- */


static struct mxr_output_conf mxr_output_conf[] = {
	{
		.output_name = "S5P HDMI connector",
		.module_name = "s5p-hdmi",
		.cookie = 1,
        },
	{
		.output_name = "S5P SDO connector",
		.module_name = "s5p-sdo",
		.cookie = 0,
        },
};


void mxr_get_mbus_fmt(struct mxr_device *mdev, struct v4l2_mbus_framefmt *mbus_fmt) { struct v4l2_subdev *sd; struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; int ret; mutex_lock(&mdev->mutex); sd = to_outsd(mdev); ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); *mbus_fmt = fmt.format; WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name); mutex_unlock(&mdev->mutex); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski6773.63%150.00%
hans verkuilhans verkuil2426.37%150.00%
Total91100.00%2100.00%


void mxr_streamer_get(struct mxr_device *mdev) { mutex_lock(&mdev->mutex); ++mdev->n_streamer; mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer); if (mdev->n_streamer == 1) { struct v4l2_subdev *sd = to_outsd(mdev); struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; struct v4l2_mbus_framefmt *mbus_fmt = &fmt.format; struct mxr_resources *res = &mdev->res; int ret; if (to_output(mdev)->cookie == 0) clk_set_parent(res->sclk_mixer, res->sclk_dac); else clk_set_parent(res->sclk_mixer, res->sclk_hdmi); mxr_reg_s_output(mdev, to_output(mdev)->cookie); ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name); ret = v4l2_subdev_call(sd, video, s_stream, 1); WARN(ret, "starting stream failed for output %s\n", sd->name); mxr_reg_set_mbus_fmt(mdev, mbus_fmt); mxr_reg_streamon(mdev); ret = mxr_reg_wait4vsync(mdev); WARN(ret, "failed to get vsync (%d) from output\n", ret); } mutex_unlock(&mdev->mutex); mxr_reg_dump(mdev); /* FIXME: what to do when streaming fails? */ }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski20790.39%150.00%
hans verkuilhans verkuil229.61%150.00%
Total229100.00%2100.00%


void mxr_streamer_put(struct mxr_device *mdev) { mutex_lock(&mdev->mutex); --mdev->n_streamer; mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer); if (mdev->n_streamer == 0) { int ret; struct v4l2_subdev *sd = to_outsd(mdev); mxr_reg_streamoff(mdev); /* vsync applies Mixer setup */ ret = mxr_reg_wait4vsync(mdev); WARN(ret, "failed to get vsync (%d) from output\n", ret); ret = v4l2_subdev_call(sd, video, s_stream, 0); WARN(ret, "stopping stream failed for output %s\n", sd->name); } WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n", mdev->n_streamer); mutex_unlock(&mdev->mutex); mxr_reg_dump(mdev); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski133100.00%1100.00%
Total133100.00%1100.00%


void mxr_output_get(struct mxr_device *mdev) { mutex_lock(&mdev->mutex); ++mdev->n_output; mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output); /* turn on auxiliary driver */ if (mdev->n_output == 1) v4l2_subdev_call(to_outsd(mdev), core, s_power, 1); mutex_unlock(&mdev->mutex); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski67100.00%1100.00%
Total67100.00%1100.00%


void mxr_output_put(struct mxr_device *mdev) { mutex_lock(&mdev->mutex); --mdev->n_output; mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output); /* turn on auxiliary driver */ if (mdev->n_output == 0) v4l2_subdev_call(to_outsd(mdev), core, s_power, 0); WARN(mdev->n_output < 0, "negative number of output users (%d)\n", mdev->n_output); mutex_unlock(&mdev->mutex); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski82100.00%1100.00%
Total82100.00%1100.00%


int mxr_power_get(struct mxr_device *mdev) { int ret = pm_runtime_get_sync(mdev->dev); /* returning 1 means that power is already enabled, * so zero success be returned */ if (ret < 0) return ret; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski3193.94%150.00%
arnd bergmannarnd bergmann26.06%150.00%
Total33100.00%2100.00%


void mxr_power_put(struct mxr_device *mdev) { pm_runtime_put_sync(mdev->dev); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski17100.00%1100.00%
Total17100.00%1100.00%

/* --------- RESOURCE MANAGEMENT -------------*/
static int mxr_acquire_plat_resources(struct mxr_device *mdev, struct platform_device *pdev) { struct resource *res; int ret; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr"); if (res == NULL) { mxr_err(mdev, "get memory resource failed.\n"); ret = -ENXIO; goto fail; } mdev->res.mxr_regs = ioremap(res->start, resource_size(res)); if (mdev->res.mxr_regs == NULL) { mxr_err(mdev, "register mapping failed.\n"); ret = -ENXIO; goto fail; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp"); if (res == NULL) { mxr_err(mdev, "get memory resource failed.\n"); ret = -ENXIO; goto fail_mxr_regs; } mdev->res.vp_regs = ioremap(res->start, resource_size(res)); if (mdev->res.vp_regs == NULL) { mxr_err(mdev, "register mapping failed.\n"); ret = -ENXIO; goto fail_mxr_regs; } res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq"); if (res == NULL) { mxr_err(mdev, "get interrupt resource failed.\n"); ret = -ENXIO; goto fail_vp_regs; } ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev); if (ret) { mxr_err(mdev, "request interrupt failed.\n"); goto fail_vp_regs; } mdev->res.irq = res->start; return 0; fail_vp_regs: iounmap(mdev->res.vp_regs); fail_mxr_regs: iounmap(mdev->res.mxr_regs); fail: return ret; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski289100.00%1100.00%
Total289100.00%1100.00%


static void mxr_resource_clear_clocks(struct mxr_resources *res) { res->mixer = ERR_PTR(-EINVAL); res->vp = ERR_PTR(-EINVAL); res->sclk_mixer = ERR_PTR(-EINVAL); res->sclk_hdmi = ERR_PTR(-EINVAL); res->sclk_dac = ERR_PTR(-EINVAL); }

Contributors

PersonTokensPropCommitsCommitProp
sachin kamatsachin kamat61100.00%1100.00%
Total61100.00%1100.00%


static void mxr_release_plat_resources(struct mxr_device *mdev) { free_irq(mdev->res.irq, mdev); iounmap(mdev->res.vp_regs); iounmap(mdev->res.mxr_regs); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski40100.00%1100.00%
Total40100.00%1100.00%


static void mxr_release_clocks(struct mxr_device *mdev) { struct mxr_resources *res = &mdev->res; if (!IS_ERR(res->sclk_dac)) clk_put(res->sclk_dac); if (!IS_ERR(res->sclk_hdmi)) clk_put(res->sclk_hdmi); if (!IS_ERR(res->sclk_mixer)) clk_put(res->sclk_mixer); if (!IS_ERR(res->vp)) clk_put(res->vp); if (!IS_ERR(res->mixer)) clk_put(res->mixer); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski10195.28%150.00%
sachin kamatsachin kamat54.72%150.00%
Total106100.00%2100.00%


static int mxr_acquire_clocks(struct mxr_device *mdev) { struct mxr_resources *res = &mdev->res; struct device *dev = mdev->dev; mxr_resource_clear_clocks(res); res->mixer = clk_get(dev, "mixer"); if (IS_ERR(res->mixer)) { mxr_err(mdev, "failed to get clock 'mixer'\n"); goto fail; } res->vp = clk_get(dev, "vp"); if (IS_ERR(res->vp)) { mxr_err(mdev, "failed to get clock 'vp'\n"); goto fail; } res->sclk_mixer = clk_get(dev, "sclk_mixer"); if (IS_ERR(res->sclk_mixer)) { mxr_err(mdev, "failed to get clock 'sclk_mixer'\n"); goto fail; } res->sclk_hdmi = clk_get(dev, "sclk_hdmi"); if (IS_ERR(res->sclk_hdmi)) { mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n"); goto fail; } res->sclk_dac = clk_get(dev, "sclk_dac"); if (IS_ERR(res->sclk_dac)) { mxr_err(mdev, "failed to get clock 'sclk_dac'\n"); goto fail; } return 0; fail: mxr_release_clocks(mdev); return -ENODEV; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski19995.22%133.33%
sachin kamatsachin kamat52.39%133.33%
tony prisktony prisk52.39%133.33%
Total209100.00%3100.00%


static int mxr_acquire_resources(struct mxr_device *mdev, struct platform_device *pdev) { int ret; ret = mxr_acquire_plat_resources(mdev, pdev); if (ret) goto fail; ret = mxr_acquire_clocks(mdev); if (ret) goto fail_plat; mxr_info(mdev, "resources acquired\n"); return 0; fail_plat: mxr_release_plat_resources(mdev); fail: mxr_err(mdev, "resources acquire failed\n"); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski78100.00%1100.00%
Total78100.00%1100.00%


static void mxr_release_resources(struct mxr_device *mdev) { mxr_release_clocks(mdev); mxr_release_plat_resources(mdev); memset(&mdev->res, 0, sizeof(mdev->res)); mxr_resource_clear_clocks(&mdev->res); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski3678.26%133.33%
sachin kamatsachin kamat1021.74%266.67%
Total46100.00%3100.00%


static void mxr_release_layers(struct mxr_device *mdev) { int i; for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i) if (mdev->layer[i]) mxr_layer_release(mdev->layer[i]); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski51100.00%1100.00%
Total51100.00%1100.00%


static int mxr_acquire_layers(struct mxr_device *mdev, struct mxr_platform_data *pdata) { mdev->layer[0] = mxr_graph_layer_create(mdev, 0); mdev->layer[1] = mxr_graph_layer_create(mdev, 1); mdev->layer[2] = mxr_vp_layer_create(mdev, 0); if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) { mxr_err(mdev, "failed to acquire layers\n"); goto fail; } return 0; fail: mxr_release_layers(mdev); return -ENODEV; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski110100.00%1100.00%
Total110100.00%1100.00%

/* ---------- POWER MANAGEMENT ----------- */
static int mxr_runtime_resume(struct device *dev) { struct mxr_device *mdev = to_mdev(dev); struct mxr_resources *res = &mdev->res; int ret; mxr_dbg(mdev, "resume - start\n"); mutex_lock(&mdev->mutex); /* turn clocks on */ ret = clk_prepare_enable(res->mixer); if (ret < 0) { dev_err(mdev->dev, "clk_prepare_enable(mixer) failed\n"); goto fail; } ret = clk_prepare_enable(res->vp); if (ret < 0) { dev_err(mdev->dev, "clk_prepare_enable(vp) failed\n"); goto fail_mixer; } ret = clk_prepare_enable(res->sclk_mixer); if (ret < 0) { dev_err(mdev->dev, "clk_prepare_enable(sclk_mixer) failed\n"); goto fail_vp; } /* apply default configuration */ mxr_reg_reset(mdev); mxr_dbg(mdev, "resume - finished\n"); mutex_unlock(&mdev->mutex); return 0; fail_vp: clk_disable_unprepare(res->vp); fail_mixer: clk_disable_unprepare(res->mixer); fail: mutex_unlock(&mdev->mutex); dev_err(mdev->dev, "resume failed\n"); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
mateusz krawczukmateusz krawczuk11255.72%150.00%
tomasz stanislawskitomasz stanislawski8944.28%150.00%
Total201100.00%2100.00%


static int mxr_runtime_suspend(struct device *dev) { struct mxr_device *mdev = to_mdev(dev); struct mxr_resources *res = &mdev->res; mxr_dbg(mdev, "suspend - start\n"); mutex_lock(&mdev->mutex); /* turn clocks off */ clk_disable_unprepare(res->sclk_mixer); clk_disable_unprepare(res->vp); clk_disable_unprepare(res->mixer); mutex_unlock(&mdev->mutex); mxr_dbg(mdev, "suspend - finished\n"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski8396.51%150.00%
mateusz krawczukmateusz krawczuk33.49%150.00%
Total86100.00%2100.00%

static const struct dev_pm_ops mxr_pm_ops = { .runtime_suspend = mxr_runtime_suspend, .runtime_resume = mxr_runtime_resume, }; /* --------- DRIVER INITIALIZATION ---------- */
static int mxr_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mxr_platform_data *pdata = dev->platform_data; struct mxr_device *mdev; int ret; /* mdev does not exist yet so no mxr_dbg is used */ dev_info(dev, "probe start\n"); mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); if (!mdev) { dev_err(dev, "not enough memory.\n"); ret = -ENOMEM; goto fail; } /* setup pointer to master device */ mdev->dev = dev; mutex_init(&mdev->mutex); spin_lock_init(&mdev->reg_slock); init_waitqueue_head(&mdev->event_queue); /* acquire resources: regs, irqs, clocks, regulators */ ret = mxr_acquire_resources(mdev, pdev); if (ret) goto fail_mem; /* configure resources for video output */ ret = mxr_acquire_video(mdev, mxr_output_conf, ARRAY_SIZE(mxr_output_conf)); if (ret) goto fail_resources; /* configure layers */ ret = mxr_acquire_layers(mdev, pdata); if (ret) goto fail_video; pm_runtime_enable(dev); mxr_info(mdev, "probe successful\n"); return 0; fail_video: mxr_release_video(mdev); fail_resources: mxr_release_resources(mdev); fail_mem: kfree(mdev); fail: dev_info(dev, "probe failed\n"); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski21197.69%133.33%
sachin kamatsachin kamat52.31%266.67%
Total216100.00%3100.00%


static int mxr_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mxr_device *mdev = to_mdev(dev); pm_runtime_disable(dev); mxr_release_layers(mdev); mxr_release_video(mdev); mxr_release_resources(mdev); kfree(mdev); dev_info(dev, "remove successful\n"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski6598.48%150.00%
masanari iidamasanari iida11.52%150.00%
Total66100.00%2100.00%

static struct platform_driver mxr_driver __refdata = { .probe = mxr_probe, .remove = mxr_remove, .driver = { .name = MXR_DRIVER_NAME, .pm = &mxr_pm_ops, } };
static int __init mxr_init(void) { int i, ret; static const char banner[] __initconst = "Samsung TV Mixer driver, " "(c) 2010-2011 Samsung Electronics Co., Ltd.\n"; pr_info("%s\n", banner); /* Loading auxiliary modules */ for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i) request_module(mxr_output_conf[i].module_name); ret = platform_driver_register(&mxr_driver); if (ret != 0) { pr_err("s5p-tv: registration of MIXER driver failed\n"); return -ENXIO; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski8093.02%133.33%
sachin kamatsachin kamat55.81%133.33%
uwe kleine-koeniguwe kleine-koenig11.16%133.33%
Total86100.00%3100.00%

module_init(mxr_init);
static void __exit mxr_exit(void) { platform_driver_unregister(&mxr_driver); }

Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski15100.00%1100.00%
Total15100.00%1100.00%

module_exit(mxr_exit);

Overall Contributors

PersonTokensPropCommitsCommitProp
tomasz stanislawskitomasz stanislawski220589.42%19.09%
mateusz krawczukmateusz krawczuk1154.66%19.09%
sachin kamatsachin kamat913.69%436.36%
hans verkuilhans verkuil461.87%19.09%
tony prisktony prisk50.20%19.09%
arnd bergmannarnd bergmann20.08%19.09%
uwe kleine-koeniguwe kleine-koenig10.04%19.09%
masanari iidamasanari iida10.04%19.09%
Total2466100.00%11100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}