drivers/media/platform/qcom/camss/camss-tpg.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/qcom/camss/camss-tpg.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/qcom/camss/camss-tpg.c
Extension
.c
Size
11258 bytes
Lines
520
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (clock->freq) {
			round_rate = clk_round_rate(clock->clk, clock->freq[0]);
			if (round_rate < 0) {
				dev_err(dev, "clk round rate failed: %ld\n",
					round_rate);
				return -EINVAL;
			}

			ret = clk_set_rate(clock->clk, round_rate);
			if (ret < 0) {
				dev_err(dev, "clk set rate failed: %d\n", ret);
				return ret;
			}
		}
	}

	return 0;
}

static int tpg_set_power(struct v4l2_subdev *sd, int on)
{
	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
	struct device *dev = tpg->camss->dev;

	if (on) {
		int ret;

		ret = pm_runtime_resume_and_get(dev);
		if (ret < 0)
			return ret;

		ret = tpg_set_clock_rates(tpg);
		if (ret < 0) {
			pm_runtime_put_sync(dev);
			return ret;
		}

		ret = camss_enable_clocks(tpg->nclocks, tpg->clock, dev);
		if (ret < 0) {
			pm_runtime_put_sync(dev);
			return ret;
		}

		tpg->res->hw_ops->reset(tpg);

		tpg->res->hw_ops->hw_version(tpg);
	} else {
		camss_disable_clocks(tpg->nclocks, tpg->clock);

		pm_runtime_put_sync(dev);
	}

	return 0;
}

static int tpg_set_stream(struct v4l2_subdev *sd, int enable)
{
	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
	int ret;

	if (enable) {
		ret = v4l2_ctrl_handler_setup(&tpg->ctrls);
		if (ret < 0) {
			dev_err(tpg->camss->dev,
				"could not sync v4l2 controls: %d\n", ret);
			return ret;
		}
	}

	return tpg->res->hw_ops->configure_stream(tpg, enable);
}

static struct v4l2_mbus_framefmt *
__tpg_get_format(struct tpg_device *tpg,
		 struct v4l2_subdev_state *sd_state,
		 unsigned int pad,
		 enum v4l2_subdev_format_whence which)
{
	if (which == V4L2_SUBDEV_FORMAT_TRY)
		return v4l2_subdev_state_get_format(sd_state,
						    pad);

	return &tpg->fmt;
}

static void tpg_try_format(struct tpg_device *tpg,
			   struct v4l2_mbus_framefmt *fmt)
{
	unsigned int i;

Annotation

Implementation Notes