18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * V4L2 clock service
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2012-2013, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * ATTENTION: This is a temporary API and it shall be replaced by the generic
88c2ecf20Sopenharmony_ci * clock API, when the latter becomes widely available.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef MEDIA_V4L2_CLK_H
128c2ecf20Sopenharmony_ci#define MEDIA_V4L2_CLK_H
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/atomic.h>
158c2ecf20Sopenharmony_ci#include <linux/export.h>
168c2ecf20Sopenharmony_ci#include <linux/list.h>
178c2ecf20Sopenharmony_ci#include <linux/mutex.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistruct module;
208c2ecf20Sopenharmony_cistruct device;
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct clk;
238c2ecf20Sopenharmony_cistruct v4l2_clk {
248c2ecf20Sopenharmony_ci	struct list_head list;
258c2ecf20Sopenharmony_ci	const struct v4l2_clk_ops *ops;
268c2ecf20Sopenharmony_ci	const char *dev_id;
278c2ecf20Sopenharmony_ci	int enable;
288c2ecf20Sopenharmony_ci	struct mutex lock; /* Protect the enable count */
298c2ecf20Sopenharmony_ci	atomic_t use_count;
308c2ecf20Sopenharmony_ci	struct clk *clk;
318c2ecf20Sopenharmony_ci	void *priv;
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistruct v4l2_clk_ops {
358c2ecf20Sopenharmony_ci	struct module	*owner;
368c2ecf20Sopenharmony_ci	int		(*enable)(struct v4l2_clk *clk);
378c2ecf20Sopenharmony_ci	void		(*disable)(struct v4l2_clk *clk);
388c2ecf20Sopenharmony_ci	unsigned long	(*get_rate)(struct v4l2_clk *clk);
398c2ecf20Sopenharmony_ci	int		(*set_rate)(struct v4l2_clk *clk, unsigned long);
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistruct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops,
438c2ecf20Sopenharmony_ci				   const char *dev_name,
448c2ecf20Sopenharmony_ci				   void *priv);
458c2ecf20Sopenharmony_civoid v4l2_clk_unregister(struct v4l2_clk *clk);
468c2ecf20Sopenharmony_cistruct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id);
478c2ecf20Sopenharmony_civoid v4l2_clk_put(struct v4l2_clk *clk);
488c2ecf20Sopenharmony_ciint v4l2_clk_enable(struct v4l2_clk *clk);
498c2ecf20Sopenharmony_civoid v4l2_clk_disable(struct v4l2_clk *clk);
508c2ecf20Sopenharmony_ciunsigned long v4l2_clk_get_rate(struct v4l2_clk *clk);
518c2ecf20Sopenharmony_ciint v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate);
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistruct module;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistruct v4l2_clk *__v4l2_clk_register_fixed(const char *dev_id,
568c2ecf20Sopenharmony_ci			unsigned long rate, struct module *owner);
578c2ecf20Sopenharmony_civoid v4l2_clk_unregister_fixed(struct v4l2_clk *clk);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id,
608c2ecf20Sopenharmony_ci							unsigned long rate)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	return __v4l2_clk_register_fixed(dev_id, rate, THIS_MODULE);
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define V4L2_CLK_NAME_SIZE 64
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci#define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \
688c2ecf20Sopenharmony_ci			  "%d-%04x", adap, client)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci#define v4l2_clk_name_of(name, size, node) snprintf(name, size, \
718c2ecf20Sopenharmony_ci			  "of-%pOF", node)
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci#endif
74