mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
Merge commit '19e4b7da3917191c274947a3c351fb8419c86a93'
* commit '19e4b7da3917191c274947a3c351fb8419c86a93': ASoC: rockchip: rk817-codec: fix pop from DAC_DIG_CLK_DIS and DAC_DIG_CLK_EN drm/rockchip: vop2: primary plane need consider win possible_crtcs video: rockchip: mpp: fix get drv data type err input: rockchip_pwm_remotectl: add pwm v4 support misc: rk628: optimize input and output mode information ARM: dts: rockchip: rk3036-evb1-ddr3-v10: unify the rk628 node name of interface in dts arm64: dts: rockchip: rk3568-evb-rk628: unify the node name of interface in dts misc: rk628: unify the node name of interface in dts drm/panel: panel-simple: power-on and power-off timing optimization media: i2c: rk628: add suspend and resume support video: rockchip: mpp: fix get drv data type err soc: rockchip: ipa: Avoid NULL pointer when get static power media: rockchip: vicap update frame buffer with real frame phase when work with multi_dev combine to one Change-Id: Ic8624574b49550b1b25deafca4c9c906a8cb5700
This commit is contained in:
@@ -231,8 +231,8 @@
|
||||
reset-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>;
|
||||
plugin-det-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>;
|
||||
status = "okay";
|
||||
rk628,hdmi-in;
|
||||
rk628-dsi {
|
||||
rk628-hdmi-in;
|
||||
rk628-dsi-out {
|
||||
//rockchip,dual-channel;
|
||||
dsi,eotp;
|
||||
dsi,video-mode;
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
panel-unprepare-delay-ms = <10>;
|
||||
panel-disable-delay-ms = <60>;
|
||||
|
||||
rk628,hdmi-in;
|
||||
rk628-dsi {
|
||||
rk628-hdmi-in;
|
||||
rk628-dsi-out {
|
||||
//rockchip,dual-channel;
|
||||
dsi,eotp;
|
||||
dsi,video-mode;
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
panel-disable-delay-ms = <240>;
|
||||
panel-init-delay-ms = <240>;
|
||||
|
||||
rk628,hdmi-in;
|
||||
rk628-dsi {
|
||||
rk628-hdmi-in;
|
||||
rk628-dsi-out {
|
||||
rockchip,lane-mbps = <1100>;
|
||||
rockchip,dual-channel;
|
||||
dsi,eotp;
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
clocks = <&pmucru CLK_WIFI>;
|
||||
clock-names = "soc_24M";
|
||||
|
||||
rk628,hdmi-in;
|
||||
rk628-gvi {
|
||||
rk628-hdmi-in;
|
||||
rk628-gvi-out {
|
||||
/* "rgb666"
|
||||
* "rgb888"
|
||||
* "rgb101010"
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
panel-unprepare-delay-ms = <10>;
|
||||
panel-disable-delay-ms = <60>;
|
||||
|
||||
rk628,hdmi-in;
|
||||
rk628-lvds {
|
||||
rk628-hdmi-in;
|
||||
rk628-lvds-out {
|
||||
/* "jeida_18","vesa_24","vesa_18" */
|
||||
bus-format = "jeida_24";
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
panel-unprepare-delay-ms = <10>;
|
||||
panel-disable-delay-ms = <60>;
|
||||
|
||||
rk628,hdmi-in;
|
||||
rk628-lvds {
|
||||
rk628-hdmi-in;
|
||||
rk628-lvds-out {
|
||||
/* "jeida_18","vesa_24","vesa_18" */
|
||||
bus-format = "vesa_24";
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
panel-unprepare-delay-ms = <10>;
|
||||
panel-disable-delay-ms = <60>;
|
||||
|
||||
rk628,rgb-in;
|
||||
rk628-dsi {
|
||||
rk628-rgb-in;
|
||||
rk628-dsi-out {
|
||||
//rockchip,dual-channel;
|
||||
dsi,eotp;
|
||||
dsi,video-mode;
|
||||
|
||||
@@ -62,8 +62,8 @@
|
||||
clocks = <&pmucru CLK_WIFI>;
|
||||
clock-names = "soc_24M";
|
||||
|
||||
rk628,rgb-in;
|
||||
rk628-gvi {
|
||||
rk628-rgb-in;
|
||||
rk628-gvi-out {
|
||||
/* "rgb666"
|
||||
* "rgb888"
|
||||
* "rgb101010"
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&rk628_reset &refclk_pins>;
|
||||
|
||||
rk628,rgb-in;
|
||||
rk628,hdmi-out;
|
||||
rk628-rgb-in;
|
||||
rk628-hdmi-out;
|
||||
status = "okay";
|
||||
|
||||
port {
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
panel-unprepare-delay-ms = <10>;
|
||||
panel-disable-delay-ms = <60>;
|
||||
|
||||
rk628,rgb-in;
|
||||
rk628-lvds {
|
||||
rk628-rgb-in;
|
||||
rk628-lvds-out {
|
||||
/* "jeida_18","vesa_24","vesa_18" */
|
||||
bus-format = "jeida_24";
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
panel-unprepare-delay-ms = <10>;
|
||||
panel-disable-delay-ms = <60>;
|
||||
|
||||
rk628,rgb-in;
|
||||
rk628-lvds {
|
||||
rk628-rgb-in;
|
||||
rk628-lvds-out {
|
||||
/* "jeida_18","vesa_24","vesa_18" */
|
||||
bus-format = "vesa_24";
|
||||
|
||||
|
||||
@@ -218,6 +218,8 @@ struct panel_simple {
|
||||
|
||||
struct drm_dsc_picture_parameter_set *pps;
|
||||
enum drm_panel_orientation orientation;
|
||||
|
||||
bool loader_protect;
|
||||
};
|
||||
|
||||
static inline void panel_simple_msleep(unsigned int msecs)
|
||||
@@ -536,6 +538,8 @@ int panel_simple_loader_protect(struct drm_panel *panel)
|
||||
struct panel_simple *p = to_panel_simple(panel);
|
||||
int err;
|
||||
|
||||
p->loader_protect = true;
|
||||
|
||||
err = pm_runtime_get_sync(panel->dev);
|
||||
if (err < 0) {
|
||||
pm_runtime_put_autosuspend(panel->dev);
|
||||
@@ -567,15 +571,25 @@ static int panel_simple_disable(struct drm_panel *panel)
|
||||
static int panel_simple_suspend(struct device *dev)
|
||||
{
|
||||
struct panel_simple *p = dev_get_drvdata(dev);
|
||||
struct drm_panel *panel = &p->base;
|
||||
|
||||
if (p->desc->exit_seq) {
|
||||
if (p->desc->cmd_type == CMD_TYPE_SPI) {
|
||||
if (panel_simple_xfer_spi_cmd_seq(p, p->desc->exit_seq)) {
|
||||
dev_err(panel->dev, "failed to send exit spi cmds seq\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (p->dsi)
|
||||
panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq);
|
||||
}
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(p->reset_gpio, 1);
|
||||
gpiod_set_value_cansleep(p->enable_gpio, 0);
|
||||
|
||||
panel_simple_regulator_disable(p);
|
||||
|
||||
if (p->desc->delay.unprepare)
|
||||
panel_simple_msleep(p->desc->delay.unprepare);
|
||||
|
||||
p->unprepared_time = ktime_get_boottime();
|
||||
|
||||
kfree(p->edid);
|
||||
@@ -593,18 +607,6 @@ static int panel_simple_unprepare(struct drm_panel *panel)
|
||||
if (!p->prepared)
|
||||
return 0;
|
||||
|
||||
if (p->desc->exit_seq) {
|
||||
if (p->desc->cmd_type == CMD_TYPE_SPI) {
|
||||
if (panel_simple_xfer_spi_cmd_seq(p, p->desc->exit_seq)) {
|
||||
dev_err(panel->dev, "failed to send exit spi cmds seq\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (p->dsi)
|
||||
panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq);
|
||||
}
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(panel->dev);
|
||||
ret = pm_runtime_put_autosuspend(panel->dev);
|
||||
if (ret < 0)
|
||||
@@ -617,6 +619,7 @@ static int panel_simple_unprepare(struct drm_panel *panel)
|
||||
static int panel_simple_resume(struct device *dev)
|
||||
{
|
||||
struct panel_simple *p = dev_get_drvdata(dev);
|
||||
struct drm_panel *panel = &p->base;
|
||||
int err;
|
||||
|
||||
panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare);
|
||||
@@ -634,22 +637,9 @@ static int panel_simple_resume(struct device *dev)
|
||||
|
||||
p->prepared_time = ktime_get_boottime();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panel_simple_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct panel_simple *p = to_panel_simple(panel);
|
||||
int ret;
|
||||
|
||||
/* Preparing when already prepared is a no-op */
|
||||
if (p->prepared)
|
||||
if (p->loader_protect) {
|
||||
p->loader_protect = false;
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_get_sync(panel->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_autosuspend(panel->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(p->reset_gpio, 1);
|
||||
@@ -674,6 +664,24 @@ static int panel_simple_prepare(struct drm_panel *panel)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panel_simple_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct panel_simple *p = to_panel_simple(panel);
|
||||
int ret;
|
||||
|
||||
/* Preparing when already prepared is a no-op */
|
||||
if (p->prepared)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_get_sync(panel->dev);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put_autosuspend(panel->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
p->prepared = true;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -11299,6 +11299,12 @@ static int vop2_crtc_create_post_csc_property(struct vop2 *vop2, struct drm_crtc
|
||||
#define RK3566_MIRROR_PLANE_MASK (BIT(ROCKCHIP_VOP2_CLUSTER1) | BIT(ROCKCHIP_VOP2_ESMART1) | \
|
||||
BIT(ROCKCHIP_VOP2_SMART1))
|
||||
|
||||
static inline bool vop2_win_can_link_to_vp(struct vop2_video_port *vp, struct vop2_win *win)
|
||||
{
|
||||
return (!win->possible_crtcs ||
|
||||
(win->possible_crtcs && (win->possible_crtcs & BIT(vp->id))));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* Registered crtc number on success, negative error code on failure.
|
||||
@@ -11414,14 +11420,17 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
plane_mask &= ~RK3566_MIRROR_PLANE_MASK;
|
||||
}
|
||||
}
|
||||
find_primary_plane = false;
|
||||
|
||||
if (vp->primary_plane_phy_id >= 0) {
|
||||
win = vop2_find_win_by_phys_id(vop2, vp->primary_plane_phy_id);
|
||||
if (win) {
|
||||
if (win && vop2_win_can_link_to_vp(vp, win)) {
|
||||
find_primary_plane = true;
|
||||
win->type = DRM_PLANE_TYPE_PRIMARY;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!find_primary_plane) {
|
||||
j = 0;
|
||||
while (j < vop2->registered_num_wins) {
|
||||
be_used_for_primary_plane = false;
|
||||
@@ -11434,6 +11443,9 @@ static int vop2_create_crtc(struct vop2 *vop2)
|
||||
if (win->type != DRM_PLANE_TYPE_PRIMARY)
|
||||
continue;
|
||||
|
||||
if (!vop2_win_can_link_to_vp(vp, win))
|
||||
continue;
|
||||
|
||||
for (k = 0; k < vop2_data->nr_vps; k++) {
|
||||
if (win->phys_id == vop2->vps[k].primary_plane_phy_id) {
|
||||
be_used_for_primary_plane = true;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
@@ -19,8 +20,6 @@
|
||||
#include <linux/rockchip/rockchip_sip.h>
|
||||
#include "rockchip_pwm_remotectl.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* sys/module/rk_pwm_remotectl/parameters,
|
||||
* modify code_print to change the value
|
||||
@@ -56,8 +55,46 @@ struct rkxx_remotectl_button {
|
||||
struct rkxx_remote_key_table key_table[MAX_NUM_KEYS];
|
||||
};
|
||||
|
||||
struct rk_remote_pwm_regs {
|
||||
unsigned long ctrl;
|
||||
unsigned long version;
|
||||
unsigned long enable;
|
||||
unsigned long clk_ctrl;
|
||||
unsigned long offset;
|
||||
unsigned long rpt;
|
||||
unsigned long hpr;
|
||||
unsigned long lpr;
|
||||
unsigned long intsts;
|
||||
unsigned long int_en;
|
||||
unsigned long pwrmatch_arbiter;
|
||||
unsigned long pwrmatch_ctrl;
|
||||
unsigned long pwrmatch_lpre;
|
||||
unsigned long pwrmatch_hpre;
|
||||
unsigned long pwrmatch_ld;
|
||||
unsigned long pwrmatch_hd_zero;
|
||||
unsigned long pwrmatch_hd_one;
|
||||
unsigned long pwrmatch_value0;
|
||||
unsigned long pwrcapture_value;
|
||||
};
|
||||
|
||||
struct rk_remote_pwm_funcs {
|
||||
irqreturn_t (*irq_handler)(int irq, void *data);
|
||||
void (*int_ctrl)(struct platform_device *pdev, int work_mode);
|
||||
int (*init_hw)(struct platform_device *pdev);
|
||||
};
|
||||
|
||||
struct rk_remote_pwm_data {
|
||||
struct rk_remote_pwm_regs regs;
|
||||
struct rk_remote_pwm_funcs funcs;
|
||||
unsigned int prescaler;
|
||||
u32 enable_conf;
|
||||
int pwm_version;
|
||||
int pwrmactch_key_max;
|
||||
};
|
||||
|
||||
struct rkxx_remotectl_drvdata {
|
||||
void __iomem *base;
|
||||
int pwm_version;
|
||||
int state;
|
||||
int nbuttons;
|
||||
int scandata;
|
||||
@@ -81,10 +118,60 @@ struct rkxx_remotectl_drvdata {
|
||||
struct timer_list timer;
|
||||
struct tasklet_struct remote_tasklet;
|
||||
struct wake_lock remotectl_wake_lock;
|
||||
const struct rk_remote_pwm_data *pwm_data;
|
||||
};
|
||||
|
||||
static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id);
|
||||
static irqreturn_t rockchip_pwm_irq_v4(int irq, void *dev_id);
|
||||
static int rk_pwm_remotectl_hw_init(struct platform_device *pdev);
|
||||
static int rk_pwm_remotectl_hw_init_v4(struct platform_device *pdev);
|
||||
static void rk_pwm_int_ctrl(struct platform_device *pdev, int work_mode);
|
||||
static void rk_pwm_int_ctrl_v4(struct platform_device *pdev, int work_mode);
|
||||
|
||||
static struct rkxx_remotectl_button *remotectl_button;
|
||||
|
||||
struct rk_remote_pwm_data pwm_data_v1 = {
|
||||
.regs = {
|
||||
.version = 0x5c,
|
||||
.ctrl = 0x0c,
|
||||
},
|
||||
.prescaler = 1,
|
||||
.pwm_version = 1,
|
||||
.funcs = {
|
||||
.irq_handler = rockchip_pwm_irq,
|
||||
.int_ctrl = rk_pwm_int_ctrl,
|
||||
.init_hw = rk_pwm_remotectl_hw_init,
|
||||
},
|
||||
};
|
||||
|
||||
struct rk_remote_pwm_data pwm_data_v4 = {
|
||||
.regs = {
|
||||
.version = 0x0,
|
||||
.enable = 0x4,
|
||||
.clk_ctrl = 0x8,
|
||||
.ctrl = 0xc,
|
||||
.hpr = 0x2c,
|
||||
.lpr = 0x30,
|
||||
.intsts = 0x70,
|
||||
.int_en = 0x74,
|
||||
.pwrmatch_arbiter = 0x100,
|
||||
.pwrmatch_ctrl = 0x104,
|
||||
.pwrmatch_lpre = 0x108,
|
||||
.pwrmatch_hpre = 0x10c,
|
||||
.pwrmatch_ld = 0x110,
|
||||
.pwrmatch_hd_zero = 0x114,
|
||||
.pwrmatch_hd_one = 0x118,
|
||||
.pwrmatch_value0 = 0x11c,
|
||||
.pwrcapture_value = 0x15c,
|
||||
},
|
||||
.pwm_version = 4,
|
||||
.funcs = {
|
||||
.irq_handler = rockchip_pwm_irq_v4,
|
||||
.int_ctrl = rk_pwm_int_ctrl_v4,
|
||||
.init_hw = rk_pwm_remotectl_hw_init_v4,
|
||||
},
|
||||
};
|
||||
|
||||
static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata)
|
||||
{
|
||||
int i;
|
||||
@@ -100,7 +187,6 @@ static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int remotectl_keycode_lookup(struct rkxx_remotectl_drvdata *ddata)
|
||||
{
|
||||
int i;
|
||||
@@ -137,7 +223,6 @@ static int rk_remotectl_get_irkeybd_count(struct platform_device *pdev)
|
||||
return boardnum;
|
||||
}
|
||||
|
||||
|
||||
static int rk_remotectl_parse_ir_keys(struct platform_device *pdev)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
@@ -182,8 +267,6 @@ static int rk_remotectl_parse_ir_keys(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void rk_pwm_remotectl_do_something(unsigned long data)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata;
|
||||
@@ -359,70 +442,184 @@ static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev)
|
||||
static irqreturn_t rockchip_pwm_irq_v4(int irq, void *dev_id)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata = dev_id;
|
||||
int tmp;
|
||||
int val;
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
val = readl_relaxed(ddata->base + PWM_REG_INTSTS_V4);
|
||||
|
||||
if (val & CAP_LPR_INT) {
|
||||
writel_relaxed(CAP_LPR_INT, ddata->base + PWM_REG_INTSTS_V4);
|
||||
tmp = readl_relaxed(ddata->base + PWM_REG_HPR_V4);
|
||||
ddata->period = ddata->pwm_freq_nstime * tmp / 1000;
|
||||
DBG("period = %ld\n", ddata->period);
|
||||
tasklet_hi_schedule(&ddata->remote_tasklet);
|
||||
ret = IRQ_HANDLED;
|
||||
} else if (val & CAP_HPR_INT) {
|
||||
writel_relaxed(CAP_HPR_INT, ddata->base + PWM_REG_INTSTS_V4);
|
||||
tmp = readl_relaxed(ddata->base + PWM_REG_LPR_V4);
|
||||
DBG("lpr = %d\n", tmp);
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (val & PWR_INT) {
|
||||
writel_relaxed(PWR_INT, ddata->base + PWM_REG_INTSTS_V4);
|
||||
tmp = readl_relaxed(ddata->base + PWM_REG_CAPTURE_VALUE_V4);
|
||||
DBG("##### cap_val = 0x%0x\n", tmp);
|
||||
ddata->pwrkey_wakeup = 1;
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (ddata->state == RMC_PRELOAD)
|
||||
wake_lock_timeout(&ddata->remotectl_wake_lock, HZ);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk_pwmkey_convert_val(int min, int max, int freq_nstime)
|
||||
{
|
||||
int val, min_temp, max_temp;
|
||||
|
||||
min_temp = min * 1000 / freq_nstime;
|
||||
max_temp = max * 1000 / freq_nstime;
|
||||
val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int rockchip_pwm_set_pwrmatch(struct platform_device *pdev)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
int val, min_temp, max_temp;
|
||||
unsigned int pwm_id = ddata->remote_pwm_id;
|
||||
int version;
|
||||
int i, j;
|
||||
int num = 0;
|
||||
int ret = -1;
|
||||
int pwr_irq;
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
ddata->pwm_pwrkey_capture = 0;
|
||||
version = readl_relaxed(ddata->base + RK_PWM_VERSION_ID(pwm_id));
|
||||
dev_info(&pdev->dev, "pwm version is 0x%x\n", version & 0xffff0000);
|
||||
DBG("remote pwm version is 0x%x\n", version);
|
||||
if (((version >> 24) & 0xFF) < 2) {
|
||||
dev_info(&pdev->dev, "pwm version is less v2.0\n");
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
pwr_irq = platform_get_irq(pdev, 1);
|
||||
if (pwr_irq < 0) {
|
||||
dev_err(&pdev->dev, "cannot find PWR IRQ\n");
|
||||
ret = pwr_irq;
|
||||
goto end;
|
||||
}
|
||||
ret = devm_request_irq(&pdev->dev, pwr_irq, rockchip_pwm_pwrirq,
|
||||
IRQF_NO_SUSPEND, "rk_pwm_pwr_irq", ddata);
|
||||
IRQF_NO_SUSPEND, "rk_pwm_pwr_irq", ddata);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot claim PWR_IRQ!!!\n");
|
||||
goto end;
|
||||
}
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFFFFFFFE) | PWM_DISABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
val = (val & 0xFFFFFF7F) | PWM_PWR_INT_ENABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
|
||||
val = CH3_PWRKEY_ENABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_CTRL(pwm_id));
|
||||
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFFFFFFFE) | PWM_ENABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
return 0;
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_pwm_set_pwrmatch_v4(struct rkxx_remotectl_drvdata *pd)
|
||||
{
|
||||
int version;
|
||||
int channel_id;
|
||||
int val;
|
||||
|
||||
version = readl_relaxed(pd->base + PWM_REG_VERSION_V4);
|
||||
DBG("remote pwm version is 0x%x\n", version);
|
||||
channel_id = (version & CHANNLE_INDEX_MASK) >> CHANNLE_INDEX_SHIFT;
|
||||
val = BIT(channel_id) << PWRMATCH_READ_LOCK_SHIFT |
|
||||
BIT(channel_id) << PWRMATCH_GRANT_SHIFT;
|
||||
writel_relaxed(val, pd->base + PWM_REG_MATCH_ARBITER_V4);
|
||||
writel_relaxed(PWRKEY_EN(true),
|
||||
pd->base + PWM_REG_MATCH_CTRL_V4);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rockchip_pwrmatch_set_nec_param(struct rkxx_remotectl_drvdata *pd)
|
||||
{
|
||||
unsigned int pwm_id = pd->remote_pwm_id;
|
||||
void __iomem *reg;
|
||||
int freq_nstime;
|
||||
int val;
|
||||
|
||||
freq_nstime = pd->pwm_freq_nstime;
|
||||
//preloader low min:8000us, max:10000us
|
||||
min_temp = RK_PWM_TIME_PRE_MIN_LOW * 1000 / ddata->pwm_freq_nstime;
|
||||
max_temp = RK_PWM_TIME_PRE_MAX_LOW * 1000 / ddata->pwm_freq_nstime;
|
||||
val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_LPRE(pwm_id));
|
||||
val = rk_pwmkey_convert_val(RK_PWM_TIME_PRE_MIN_LOW,
|
||||
RK_PWM_TIME_PRE_MAX_LOW, freq_nstime);
|
||||
if (pd->pwm_data->pwm_version < 4)
|
||||
reg = pd->base + PWM_REG_PWRMATCH_LPRE(pwm_id);
|
||||
else
|
||||
reg = pd->base + PWM_REG_MATCH_LPRE_V4;
|
||||
writel_relaxed(val, reg);
|
||||
|
||||
//preloader higt min:4000us, max:5000us
|
||||
min_temp = RK_PWM_TIME_PRE_MIN * 1000 / ddata->pwm_freq_nstime;
|
||||
max_temp = RK_PWM_TIME_PRE_MAX * 1000 / ddata->pwm_freq_nstime;
|
||||
val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HPRE(pwm_id));
|
||||
val = rk_pwmkey_convert_val(RK_PWM_TIME_PRE_MIN,
|
||||
RK_PWM_TIME_PRE_MAX, freq_nstime);
|
||||
if (pd->pwm_data->pwm_version < 4)
|
||||
reg = pd->base + PWM_REG_PWRMATCH_HPRE(pwm_id);
|
||||
else
|
||||
reg = pd->base + PWM_REG_MATCH_HPRE_V4;
|
||||
writel_relaxed(val, reg);
|
||||
|
||||
//logic 0/1 low min:480us, max 700us
|
||||
min_temp = RK_PWM_TIME_BIT_MIN_LOW * 1000 / ddata->pwm_freq_nstime;
|
||||
max_temp = RK_PWM_TIME_BIT_MAX_LOW * 1000 / ddata->pwm_freq_nstime;
|
||||
val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_LD(pwm_id));
|
||||
val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT_MIN_LOW,
|
||||
RK_PWM_TIME_BIT_MAX_LOW, freq_nstime);
|
||||
if (pd->pwm_data->pwm_version < 4)
|
||||
reg = pd->base + PWM_REG_PWRMATCH_LD(pwm_id);
|
||||
else
|
||||
reg = pd->base + PWM_REG_MATCH_LD_V4;
|
||||
writel_relaxed(val, reg);
|
||||
|
||||
//logic 0 higt min:480us, max 700us
|
||||
min_temp = RK_PWM_TIME_BIT0_MIN * 1000 / ddata->pwm_freq_nstime;
|
||||
max_temp = RK_PWM_TIME_BIT0_MAX * 1000 / ddata->pwm_freq_nstime;
|
||||
val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HD_ZERO(pwm_id));
|
||||
val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT0_MIN,
|
||||
RK_PWM_TIME_BIT0_MAX, freq_nstime);
|
||||
if (pd->pwm_data->pwm_version < 4)
|
||||
reg = pd->base + PWM_REG_PWRMATCH_HD_ZERO(pwm_id);
|
||||
else
|
||||
reg = pd->base + PWM_REG_MATCH_HD_ZERO_V4;
|
||||
writel_relaxed(val, reg);
|
||||
|
||||
//logic 1 higt min:1300us, max 2000us
|
||||
min_temp = RK_PWM_TIME_BIT1_MIN * 1000 / ddata->pwm_freq_nstime;
|
||||
max_temp = RK_PWM_TIME_BIT1_MAX * 1000 / ddata->pwm_freq_nstime;
|
||||
val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HD_ONE(pwm_id));
|
||||
val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT1_MIN,
|
||||
RK_PWM_TIME_BIT1_MAX, freq_nstime);
|
||||
if (pd->pwm_data->pwm_version < 4)
|
||||
reg = pd->base + PWM_REG_PWRMATCH_HD_ONE(pwm_id);
|
||||
else
|
||||
reg = pd->base + PWM_REG_MATCH_HD_ONE_V4;
|
||||
writel_relaxed(val, reg);
|
||||
}
|
||||
|
||||
for (j = 0; j < ddata->maxkeybdnum; j++) {
|
||||
static void rockchip_pwrmatch_set_pwrkey(struct rkxx_remotectl_drvdata *pd)
|
||||
{
|
||||
unsigned int pwm_id = pd->remote_pwm_id;
|
||||
void __iomem *reg;
|
||||
int i, j;
|
||||
int num = 0, num_max;
|
||||
|
||||
if (pd->pwm_data->pwm_version < 4) {
|
||||
reg = pd->base + PWM_PWRMATCH_VALUE(pwm_id);
|
||||
num_max = PWM_PWR_KEY_CAPURURE_MAX;
|
||||
} else {
|
||||
reg = pd->base + PWM_REG_CAPTURE_VALUE0_V4;
|
||||
num_max = PWM_PWR_KEY_CAPURURE_MAX_V4;
|
||||
}
|
||||
for (j = 0; j < pd->maxkeybdnum; j++) {
|
||||
for (i = 0; i < remotectl_button[j].nbuttons; i++) {
|
||||
int scancode, usercode, pwrkey;
|
||||
|
||||
@@ -434,71 +631,122 @@ static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev)
|
||||
pwrkey = usercode;
|
||||
pwrkey |= (scancode << 24) | ((~scancode & 0xff) << 16);
|
||||
DBG("pwrkey = %x\n", pwrkey);
|
||||
writel_relaxed(pwrkey, ddata->base
|
||||
+ PWM_PWRMATCH_VALUE(pwm_id) + num * 4);
|
||||
writel_relaxed(pwrkey, reg + num * 4);
|
||||
num++;
|
||||
if (num >= PWM_PWR_KEY_CAPURURE_MAX)
|
||||
if (num >= num_max)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
val = (val & 0xFFFFFF7F) | PWM_PWR_INT_ENABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
int ret = -1;
|
||||
|
||||
val = CH3_PWRKEY_ENABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_CTRL(pwm_id));
|
||||
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFFFFFFFE) | PWM_ENABLE;
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
ddata->pwm_pwrkey_capture = 0;
|
||||
if (ddata->pwm_data->pwm_version < 4) {
|
||||
ret = rockchip_pwm_set_pwrmatch(pdev);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
} else {
|
||||
rockchip_pwm_set_pwrmatch_v4(ddata);
|
||||
}
|
||||
rockchip_pwrmatch_set_nec_param(ddata);
|
||||
rockchip_pwrmatch_set_pwrkey(ddata);
|
||||
ddata->pwm_pwrkey_capture = 1;
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rk_pwm_int_ctrl(void __iomem *pwm_base, uint pwm_id, int ctrl)
|
||||
static void rk_pwm_int_ctrl(struct platform_device *pdev, int work_mode)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
int val;
|
||||
int pwm_id = ddata->remote_pwm_id;
|
||||
|
||||
if (pwm_id > 3)
|
||||
return;
|
||||
val = readl_relaxed(pwm_base + PWM_REG_INT_EN(pwm_id));
|
||||
if (ctrl) {
|
||||
val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
if (work_mode) {
|
||||
val |= PWM_CH_INT_ENABLE(pwm_id);
|
||||
DBG("pwm int enabled, value is 0x%x\n", val);
|
||||
writel_relaxed(val, pwm_base + PWM_REG_INT_EN(pwm_id));
|
||||
writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
} else {
|
||||
val &= ~PWM_CH_INT_ENABLE(pwm_id);
|
||||
DBG("pwm int disabled, value is 0x%x\n", val);
|
||||
}
|
||||
writel_relaxed(val, pwm_base + PWM_REG_INT_EN(pwm_id));
|
||||
writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id));
|
||||
}
|
||||
|
||||
static int rk_pwm_remotectl_hw_init(void __iomem *pwm_base, uint pwm_id)
|
||||
static void rk_pwm_int_ctrl_v4(struct platform_device *pdev, int work_mode)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
int val;
|
||||
|
||||
if (pwm_id > 3)
|
||||
return -1;
|
||||
if (work_mode) {
|
||||
val = CAP_LPR_INT_EN(true) | CAP_HPR_INT_EN(true) | PWR_INT_EN(false);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_INT_EN_V4);
|
||||
} else {
|
||||
val = CAP_LPR_INT_EN(false) | CAP_HPR_INT_EN(false) | PWR_INT_EN(true);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_INT_EN_V4);
|
||||
}
|
||||
}
|
||||
|
||||
static int rk_pwm_remotectl_hw_init(struct platform_device *pdev)
|
||||
{
|
||||
int val;
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
|
||||
//1. disabled pwm
|
||||
val = readl_relaxed(pwm_base + PWM_REG_CTRL);
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFFFFFFFE) | PWM_DISABLE;
|
||||
writel_relaxed(val, pwm_base + PWM_REG_CTRL);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
|
||||
//2. capture mode
|
||||
val = readl_relaxed(pwm_base + PWM_REG_CTRL);
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE;
|
||||
writel_relaxed(val, pwm_base + PWM_REG_CTRL);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
|
||||
//set clk div, clk div to 64
|
||||
val = readl_relaxed(pwm_base + PWM_REG_CTRL);
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFF0001FF) | PWM_DIV64;
|
||||
writel_relaxed(val, pwm_base + PWM_REG_CTRL);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
|
||||
//4. enabled pwm int
|
||||
rk_pwm_int_ctrl(pwm_base, pwm_id, PWM_INT_ENABLE);
|
||||
ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE);
|
||||
|
||||
//5. enabled pwm
|
||||
val = readl_relaxed(pwm_base + PWM_REG_CTRL);
|
||||
val = readl_relaxed(ddata->base + PWM_REG_CTRL);
|
||||
val = (val & 0xFFFFFFFE) | PWM_ENABLE;
|
||||
writel_relaxed(val, pwm_base + PWM_REG_CTRL);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_pwm_remotectl_hw_init_v4(struct platform_device *pdev)
|
||||
{
|
||||
int val;
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
|
||||
//1. disabled pwm
|
||||
val = PWM_EN(false) | PWM_CLK_EN(false);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_ENABLE_V4);
|
||||
|
||||
//2. capture mode
|
||||
val = PWM_MODE(CAPTURE_MODE);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CTRL_V4);
|
||||
|
||||
//3. set clk div, clk div to 64
|
||||
val = CLK_SCALE(32);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_CLK_CTRL_V4);
|
||||
|
||||
//4. enabled pwm int
|
||||
ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE);
|
||||
|
||||
//5. enabled pwm
|
||||
val = PWM_EN(true) | PWM_CLK_EN(true);
|
||||
writel_relaxed(val, ddata->base + PWM_REG_ENABLE_V4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -573,9 +821,18 @@ static inline void rk_pwm_wakeup(struct input_dev *input)
|
||||
input_sync(input);
|
||||
}
|
||||
|
||||
static const struct of_device_id rk_pwm_of_match[] = {
|
||||
{ .compatible = "rockchip,remotectl-pwm", .data = &pwm_data_v1},
|
||||
{ .compatible = "rockchip,remotectl-pwm-v4", .data = &pwm_data_v4},
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, rk_pwm_of_match);
|
||||
|
||||
static int rk_pwm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rkxx_remotectl_drvdata *ddata;
|
||||
const struct of_device_id *id;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *r;
|
||||
struct input_dev *input;
|
||||
@@ -592,20 +849,27 @@ static int rk_pwm_probe(struct platform_device *pdev)
|
||||
int count;
|
||||
|
||||
pr_err(".. rk pwm remotectl v2.0 init\n");
|
||||
id = of_match_device(rk_pwm_of_match, &pdev->dev);
|
||||
if (!id)
|
||||
return -EINVAL;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!r) {
|
||||
dev_err(&pdev->dev, "no memory resources defined\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ddata = devm_kzalloc(&pdev->dev, sizeof(struct rkxx_remotectl_drvdata),
|
||||
GFP_KERNEL);
|
||||
if (!ddata) {
|
||||
dev_err(&pdev->dev, "failed to allocate memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ddata->pwm_data = id->data;
|
||||
ddata->state = RMC_PRELOAD;
|
||||
ddata->temp_period = 0;
|
||||
ddata->base = devm_ioremap_resource(&pdev->dev, r);
|
||||
|
||||
if (IS_ERR(ddata->base))
|
||||
return PTR_ERR(ddata->base);
|
||||
count = of_property_count_strings(np, "clock-names");
|
||||
@@ -675,14 +939,17 @@ static int rk_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
ddata->irq = irq;
|
||||
ddata->wakeup = 1;
|
||||
of_property_read_u32(np, "remote_pwm_id", &pwm_id);
|
||||
pwm_id %= 4;
|
||||
ddata->remote_pwm_id = pwm_id;
|
||||
if (pwm_id > 3) {
|
||||
dev_err(&pdev->dev, "pwm id error\n");
|
||||
goto error_pclk;
|
||||
|
||||
if (ddata->pwm_data->pwm_version < 4) {
|
||||
of_property_read_u32(np, "remote_pwm_id", &pwm_id);
|
||||
pwm_id %= 4;
|
||||
ddata->remote_pwm_id = pwm_id;
|
||||
if (pwm_id > 3) {
|
||||
dev_err(&pdev->dev, "pwm id error\n");
|
||||
goto error_pclk;
|
||||
}
|
||||
DBG("remotectl: remote pwm id=0x%x\n", pwm_id);
|
||||
}
|
||||
DBG("remotectl: remote pwm id=0x%x\n", pwm_id);
|
||||
of_property_read_u32(np, "handle_cpu_id", &cpu_id);
|
||||
ddata->handle_cpu_id = cpu_id;
|
||||
DBG("remotectl: handle cpu id=0x%x\n", cpu_id);
|
||||
@@ -710,29 +977,25 @@ static int rk_pwm_probe(struct platform_device *pdev)
|
||||
cpumask_clear(&cpumask);
|
||||
cpumask_set_cpu(cpu_id, &cpumask);
|
||||
irq_set_affinity_hint(irq, &cpumask);
|
||||
ret = devm_request_irq(&pdev->dev, irq, rockchip_pwm_irq,
|
||||
ret = devm_request_irq(&pdev->dev, irq, ddata->pwm_data->funcs.irq_handler,
|
||||
IRQF_NO_SUSPEND, "rk_pwm_irq", ddata);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "cannot claim IRQ %d\n", irq);
|
||||
goto error_irq;
|
||||
}
|
||||
|
||||
pwm_freq = clk_get_rate(clk) / 64;
|
||||
ddata->pwm_freq_nstime = 1000000000 / pwm_freq;
|
||||
rk_pwm_remotectl_hw_init(ddata->base, pwm_id);
|
||||
|
||||
ddata->pwm_data->funcs.init_hw(pdev);
|
||||
ret = rk_pwm_pwrkey_wakeup_init(pdev);
|
||||
if (!ret) {
|
||||
dev_info(&pdev->dev, "Controller support pwrkey capture\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = rk_pwm_sip_wakeup_init(pdev);
|
||||
if (ret)
|
||||
dev_info(&pdev->dev, "Donot support ATF Wakeup\n");
|
||||
else
|
||||
dev_info(&pdev->dev, "Support ATF Wakeup\n");
|
||||
|
||||
DBG("rk pwm remotectl init end!\n");
|
||||
end:
|
||||
return 0;
|
||||
@@ -754,15 +1017,13 @@ static int rk_pwm_remove(struct platform_device *pdev)
|
||||
static int remotectl_suspend(struct device *dev)
|
||||
{
|
||||
int cpu = 0;
|
||||
int pwm_id;
|
||||
struct cpumask cpumask;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
|
||||
if (ddata->pwm_pwrkey_capture) {
|
||||
pwm_id = ddata->remote_pwm_id;
|
||||
ddata->pwrkey_wakeup = 0;
|
||||
rk_pwm_int_ctrl(ddata->base, pwm_id, PWM_INT_DISABLE);
|
||||
ddata->pwm_data->funcs.int_ctrl(pdev, IR_SUSPEND_MODE);
|
||||
}
|
||||
cpumask_clear(&cpumask);
|
||||
cpumask_set_cpu(cpu, &cpumask);
|
||||
@@ -770,11 +1031,9 @@ static int remotectl_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int remotectl_resume(struct device *dev)
|
||||
{
|
||||
struct cpumask cpumask;
|
||||
int pwm_id;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev);
|
||||
int state;
|
||||
@@ -791,8 +1050,7 @@ static int remotectl_resume(struct device *dev)
|
||||
if (state == REMOTECTL_PWRKEY_WAKEUP)
|
||||
rk_pwm_wakeup(ddata->input);
|
||||
} else if (ddata->pwm_pwrkey_capture) {
|
||||
pwm_id = ddata->remote_pwm_id;
|
||||
rk_pwm_int_ctrl(ddata->base, pwm_id, PWM_INT_ENABLE);
|
||||
ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE);
|
||||
if (ddata->pwrkey_wakeup == 0)
|
||||
return 0;
|
||||
ddata->pwrkey_wakeup = 0;
|
||||
@@ -808,13 +1066,6 @@ static const struct dev_pm_ops remotectl_pm_ops = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct of_device_id rk_pwm_of_match[] = {
|
||||
{ .compatible = "rockchip,remotectl-pwm"},
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, rk_pwm_of_match);
|
||||
|
||||
static struct platform_driver rk_pwm_driver = {
|
||||
.driver = {
|
||||
.name = "remotectl-pwm",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#define MAX_NUM_KEYS 60
|
||||
#define PWM_PWR_KEY_CAPURURE_MAX 10
|
||||
#define PWM_PWR_KEY_CAPURURE_MAX_V4 16
|
||||
|
||||
/* PWM0 registers */
|
||||
#define PWM_REG_CNTR 0x00 /* Counter Register */
|
||||
@@ -93,52 +94,109 @@ enum pwm_div {
|
||||
PWM_DIV128 = (0x7 << 12),
|
||||
};
|
||||
|
||||
/*
|
||||
* regs for pwm v4
|
||||
*/
|
||||
#define PWM_REG_VERSION_V4 0x0
|
||||
#define PWM_REG_ENABLE_V4 0x4
|
||||
#define PWM_REG_CLK_CTRL_V4 0x8
|
||||
#define PWM_REG_CTRL_V4 0xC
|
||||
#define PWM_REG_HPR_V4 0x2C
|
||||
#define PWM_REG_LPR_V4 0x30
|
||||
#define PWM_REG_INTSTS_V4 0x70
|
||||
#define PWM_REG_INT_EN_V4 0x74
|
||||
#define PWM_REG_MATCH_ARBITER_V4 0x100
|
||||
#define PWM_REG_MATCH_CTRL_V4 0x104
|
||||
#define PWM_REG_MATCH_LPRE_V4 0x108
|
||||
#define PWM_REG_MATCH_HPRE_V4 0x10C
|
||||
#define PWM_REG_MATCH_LD_V4 0x110
|
||||
#define PWM_REG_MATCH_HD_ZERO_V4 0x114
|
||||
#define PWM_REG_MATCH_HD_ONE_V4 0x118
|
||||
#define PWM_REG_CAPTURE_VALUE0_V4 0x11C
|
||||
#define PWM_REG_CAPTURE_VALUE_V4 0x15C
|
||||
|
||||
|
||||
#define HIWORD_UPDATE(v, l, h) (((v) << (l)) | (GENMASK(h, l) << 16))
|
||||
|
||||
/* VERSION_ID */
|
||||
#define CHANNLE_INDEX_SHIFT 4
|
||||
#define CHANNLE_INDEX_MASK (0xf << CHANNLE_INDEX_SHIFT)
|
||||
|
||||
/* PWM_CTRL */
|
||||
#define PWM_MODE(v) HIWORD_UPDATE(v, 0, 1)
|
||||
#define CAPTURE_MODE 2
|
||||
#define CLK_SCALE(v) HIWORD_UPDATE(v, 4, 12)
|
||||
|
||||
/* INTSTS */
|
||||
#define CAP_LPR_INTSTS_SHIFT 0
|
||||
#define CAP_HPR_INTSTS_SHIFT 1
|
||||
#define PWR_INTSTS_SHIFT 5
|
||||
#define CAP_LPR_INT BIT(CAP_LPR_INTSTS_SHIFT)
|
||||
#define CAP_HPR_INT BIT(CAP_HPR_INTSTS_SHIFT)
|
||||
#define PWR_INT BIT(PWR_INTSTS_SHIFT)
|
||||
|
||||
/* INT_EN */
|
||||
#define CAP_LPR_INT_EN(v) HIWORD_UPDATE(v, 0, 0)
|
||||
#define CAP_HPR_INT_EN(v) HIWORD_UPDATE(v, 1, 1)
|
||||
#define PWR_INT_EN(v) HIWORD_UPDATE(v, 5, 5)
|
||||
|
||||
/* INT_MASK */
|
||||
#define CAP_LPR_INT_MASK(v) HIWORD_UPDATE(v, 0, 0)
|
||||
#define CAP_HPR_INT_MASK(v) HIWORD_UPDATE(v, 1, 1)
|
||||
#define PWR_INT_MASK(v) HIWORD_UPDATE(v, 5, 5)
|
||||
|
||||
/* PWRMATCH_ARBITER */
|
||||
#define PWRMATCH_GRANT_SHIFT 0
|
||||
#define PWRMATCH_READ_LOCK_SHIFT 16
|
||||
#define PWRKEY_EN(v) HIWORD_UPDATE(v, 0, 0)
|
||||
#define PWM_CLK_EN(v) HIWORD_UPDATE(v, 0, 0)
|
||||
#define PWM_EN(v) HIWORD_UPDATE(v, 1, 1)
|
||||
|
||||
|
||||
/* NEC Protocol */
|
||||
#define RK_PWM_TIME_PRE_MIN 4000
|
||||
#define RK_PWM_TIME_PRE_MAX 5000
|
||||
#define RK_PWM_TIME_PRE_MIN 4000
|
||||
#define RK_PWM_TIME_PRE_MAX 5000
|
||||
|
||||
#define RK_PWM_TIME_PRE_MIN_LOW 8000
|
||||
#define RK_PWM_TIME_PRE_MAX_LOW 10000
|
||||
#define RK_PWM_TIME_PRE_MIN_LOW 8000
|
||||
#define RK_PWM_TIME_PRE_MAX_LOW 10000
|
||||
|
||||
#define RK_PWM_TIME_BIT0_MIN 390
|
||||
#define RK_PWM_TIME_BIT0_MAX 730
|
||||
#define RK_PWM_TIME_BIT0_MIN 390
|
||||
#define RK_PWM_TIME_BIT0_MAX 730
|
||||
|
||||
#define RK_PWM_TIME_BIT1_MIN 1300
|
||||
#define RK_PWM_TIME_BIT1_MAX 2000
|
||||
#define RK_PWM_TIME_BIT1_MIN 1300
|
||||
#define RK_PWM_TIME_BIT1_MAX 2000
|
||||
|
||||
#define RK_PWM_TIME_BIT_MIN_LOW 390
|
||||
#define RK_PWM_TIME_BIT_MAX_LOW 730
|
||||
#define RK_PWM_TIME_BIT_MIN_LOW 390
|
||||
#define RK_PWM_TIME_BIT_MAX_LOW 730
|
||||
|
||||
#define RK_PWM_TIME_RPT_MIN 2000
|
||||
#define RK_PWM_TIME_RPT_MAX 2500
|
||||
#define RK_PWM_TIME_RPT_MIN 2000
|
||||
#define RK_PWM_TIME_RPT_MAX 2500
|
||||
|
||||
#define RK_PWM_TIME_SEQ1_MIN 95000
|
||||
#define RK_PWM_TIME_SEQ1_MAX 98000
|
||||
#define RK_PWM_TIME_SEQ1_MIN 95000
|
||||
#define RK_PWM_TIME_SEQ1_MAX 98000
|
||||
|
||||
#define RK_PWM_TIME_SEQ2_MIN 30000
|
||||
#define RK_PWM_TIME_SEQ2_MAX 55000
|
||||
#define RK_PWM_TIME_SEQ2_MIN 30000
|
||||
#define RK_PWM_TIME_SEQ2_MAX 55000
|
||||
|
||||
|
||||
#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10)
|
||||
#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14)
|
||||
#define RK_PWM_VERSION_ID(n) ((3 - (n)) * 0x10 + 0x2c)
|
||||
#define PWM_REG_PWRMATCH_CTRL(n) ((3 - (n)) * 0x10 + 0x50)
|
||||
#define PWM_REG_PWRMATCH_LPRE(n) ((3 - (n)) * 0x10 + 0x54)
|
||||
#define PWM_REG_PWRMATCH_HPRE(n) ((3 - (n)) * 0x10 + 0x58)
|
||||
#define PWM_REG_PWRMATCH_LD(n) ((3 - (n)) * 0x10 + 0x5C)
|
||||
#define PWM_REG_PWRMATCH_HD_ZERO(n) ((3 - (n)) * 0x10 + 0x60)
|
||||
#define PWM_REG_PWRMATCH_HD_ONE(n) ((3 - (n)) * 0x10 + 0x64)
|
||||
#define PWM_PWRMATCH_VALUE(n) ((3 - (n)) * 0x10 + 0x68)
|
||||
#define PWM_PWRCAPTURE_VALUE(n) ((3 - (n)) * 0x10 + 0x9c)
|
||||
|
||||
#define PWM_CH_INT(n) BIT(n)
|
||||
#define PWM_CH_POL(n) BIT(n+8)
|
||||
|
||||
#define PWM_CH_INT_ENABLE(n) BIT(n)
|
||||
#define PWM_PWR_INT_ENABLE BIT(7)
|
||||
#define CH3_PWRKEY_ENABLE BIT(3)
|
||||
#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10)
|
||||
#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14)
|
||||
#define RK_PWM_VERSION_ID(n) ((3 - (n)) * 0x10 + 0x2c)
|
||||
#define PWM_REG_PWRMATCH_CTRL(n) ((3 - (n)) * 0x10 + 0x50)
|
||||
#define PWM_REG_PWRMATCH_LPRE(n) ((3 - (n)) * 0x10 + 0x54)
|
||||
#define PWM_REG_PWRMATCH_HPRE(n) ((3 - (n)) * 0x10 + 0x58)
|
||||
#define PWM_REG_PWRMATCH_LD(n) ((3 - (n)) * 0x10 + 0x5C)
|
||||
#define PWM_REG_PWRMATCH_HD_ZERO(n) ((3 - (n)) * 0x10 + 0x60)
|
||||
#define PWM_REG_PWRMATCH_HD_ONE(n) ((3 - (n)) * 0x10 + 0x64)
|
||||
#define PWM_PWRMATCH_VALUE(n) ((3 - (n)) * 0x10 + 0x68)
|
||||
#define PWM_PWRCAPTURE_VALUE(n) ((3 - (n)) * 0x10 + 0x9c)
|
||||
|
||||
#define PWM_CH_INT(n) BIT(n)
|
||||
#define PWM_CH_POL(n) BIT(n+8)
|
||||
|
||||
#define PWM_CH_INT_ENABLE(n) BIT(n)
|
||||
#define PWM_PWR_INT_ENABLE BIT(7)
|
||||
#define CH3_PWRKEY_ENABLE BIT(3)
|
||||
|
||||
|
||||
typedef enum _RMC_STATE {
|
||||
@@ -149,6 +207,10 @@ typedef enum _RMC_STATE {
|
||||
RMC_SEQUENCE,
|
||||
} eRMC_STATE;
|
||||
|
||||
enum {
|
||||
IR_SUSPEND_MODE = 0,
|
||||
IR_WORK_MODE
|
||||
};
|
||||
|
||||
struct RKxx_remotectl_platform_data {
|
||||
int nbuttons;
|
||||
|
||||
@@ -820,13 +820,12 @@ static int rk628_hdmirx_phy_setup(struct v4l2_subdev *sd)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk628_bt1120_initial_setup(struct v4l2_subdev *sd)
|
||||
static void rk628_bt1120_initial(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct rk628_bt1120 *bt1120 = to_bt1120(sd);
|
||||
struct v4l2_subdev_edid def_edid;
|
||||
|
||||
/* selete int io function */
|
||||
/* select int io function */
|
||||
rk628_i2c_write(bt1120->rk628, GRF_GPIO3AB_SEL_CON, 0x30002000);
|
||||
rk628_i2c_write(bt1120->rk628, GRF_GPIO1AB_SEL_CON, HIWORD_UPDATE(0x7, 11, 8));
|
||||
/* I2S_SCKM0 */
|
||||
@@ -873,7 +872,13 @@ static void rk628_bt1120_initial_setup(struct v4l2_subdev *sd)
|
||||
def_edid.edid = edid_init_data;
|
||||
rk628_bt1120_s_edid(sd, &def_edid);
|
||||
rk628_hdmirx_set_hdcp(bt1120->rk628, &bt1120->hdcp, false);
|
||||
}
|
||||
|
||||
static void rk628_bt1120_initial_setup(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct rk628_bt1120 *bt1120 = to_bt1120(sd);
|
||||
|
||||
rk628_bt1120_initial(sd);
|
||||
if (tx_5v_power_present(sd))
|
||||
schedule_delayed_work(&bt1120->delayed_work_enable_hotplug, 4000);
|
||||
}
|
||||
@@ -1685,6 +1690,91 @@ static irqreturn_t plugin_detect_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rk628_bt1120_power_on(struct rk628_bt1120 *bt1120)
|
||||
{
|
||||
clk_prepare_enable(bt1120->soc_24M);
|
||||
if (bt1120->enable_gpio) {
|
||||
gpiod_set_value(bt1120->enable_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
gpiod_set_value(bt1120->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(bt1120->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(bt1120->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (bt1120->power_gpio) {
|
||||
gpiod_set_value(bt1120->power_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk628_bt1120_power_off(struct rk628_bt1120 *bt1120)
|
||||
{
|
||||
if (bt1120->enable_gpio) {
|
||||
gpiod_set_value(bt1120->enable_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
gpiod_set_value(bt1120->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(bt1120->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(bt1120->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (bt1120->power_gpio) {
|
||||
gpiod_set_value(bt1120->power_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
clk_disable_unprepare(bt1120->soc_24M);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk628_bt1120_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct rk628_bt1120 *bt1120 = to_bt1120(sd);
|
||||
|
||||
v4l2_info(sd, "%s: resume!\n", __func__);
|
||||
|
||||
rk628_bt1120_power_on(bt1120);
|
||||
rk628_cru_initialize(bt1120->rk628);
|
||||
rk628_bt1120_initial(sd);
|
||||
rk628_hdmirx_plugout(sd);
|
||||
enable_irq(bt1120->hdmirx_irq);
|
||||
schedule_delayed_work(&bt1120->delayed_work_enable_hotplug,
|
||||
msecs_to_jiffies(500));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk628_bt1120_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct rk628_bt1120 *bt1120 = to_bt1120(sd);
|
||||
|
||||
v4l2_info(sd, "%s: suspend!\n", __func__);
|
||||
|
||||
disable_irq(bt1120->hdmirx_irq);
|
||||
cancel_delayed_work_sync(&bt1120->delayed_work_res_change);
|
||||
cancel_delayed_work_sync(&bt1120->delayed_work_enable_hotplug);
|
||||
rk628_hdmirx_audio_cancel_work_audio(bt1120->audio_info, true);
|
||||
rk628_bt1120_power_off(bt1120);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rk628_bt1120_pm_ops = {
|
||||
.suspend = rk628_bt1120_suspend,
|
||||
.resume = rk628_bt1120_resume,
|
||||
};
|
||||
|
||||
static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120)
|
||||
{
|
||||
struct device *dev = bt1120->dev;
|
||||
@@ -1701,28 +1791,27 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120)
|
||||
ret = PTR_ERR(bt1120->soc_24M);
|
||||
dev_err(dev, "Unable to get soc_24M: %d\n", ret);
|
||||
}
|
||||
clk_prepare_enable(bt1120->soc_24M);
|
||||
|
||||
bt1120->enable_gpio = devm_gpiod_get_optional(dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(bt1120->enable_gpio)) {
|
||||
ret = PTR_ERR(bt1120->enable_gpio);
|
||||
dev_err(dev, "failed to request enable GPIO: %d\n", ret);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bt1120->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(bt1120->reset_gpio)) {
|
||||
ret = PTR_ERR(bt1120->reset_gpio);
|
||||
dev_err(dev, "failed to request reset GPIO: %d\n", ret);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bt1120->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(bt1120->power_gpio)) {
|
||||
dev_err(dev, "failed to get power gpio\n");
|
||||
ret = PTR_ERR(bt1120->power_gpio);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bt1120->plugin_det_gpio = devm_gpiod_get_optional(dev, "plugin-det",
|
||||
@@ -1730,26 +1819,10 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120)
|
||||
if (IS_ERR(bt1120->plugin_det_gpio)) {
|
||||
dev_err(dev, "failed to get hdmirx det gpio\n");
|
||||
ret = PTR_ERR(bt1120->plugin_det_gpio);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
bt1120->rk628->hdmirx_det_gpio = bt1120->plugin_det_gpio;
|
||||
|
||||
if (bt1120->enable_gpio) {
|
||||
gpiod_set_value(bt1120->enable_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
gpiod_set_value(bt1120->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(bt1120->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(bt1120->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (bt1120->power_gpio) {
|
||||
gpiod_set_value(bt1120->power_gpio, 1);
|
||||
usleep_range(500, 510);
|
||||
}
|
||||
|
||||
if (of_property_read_bool(dev->of_node, "hdcp-enable"))
|
||||
hdcp1x_enable = true;
|
||||
|
||||
@@ -1769,14 +1842,14 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120)
|
||||
if (!ep) {
|
||||
dev_err(dev, "missing endpoint node\n");
|
||||
ret = -EINVAL;
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
|
||||
of_node_put(ep);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to parse endpoint\n");
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bt1120->enable_hdcp = hdcp1x_enable;
|
||||
@@ -1793,9 +1866,6 @@ static int rk628_bt1120_probe_of(struct rk628_bt1120 *bt1120)
|
||||
|
||||
v4l2_fwnode_endpoint_free(&endpoint);
|
||||
|
||||
clk_put:
|
||||
clk_disable_unprepare(bt1120->soc_24M);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1855,6 +1925,7 @@ static int rk628_bt1120_probe(struct i2c_client *client,
|
||||
return err;
|
||||
}
|
||||
|
||||
rk628_bt1120_power_on(bt1120);
|
||||
rk628_cru_initialize(rk628);
|
||||
|
||||
rk628_version_parse(rk628);
|
||||
@@ -2007,6 +2078,7 @@ err_hdl:
|
||||
mutex_destroy(&bt1120->confctl_mutex);
|
||||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(&bt1120->hdl);
|
||||
rk628_bt1120_power_off(bt1120);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2039,6 +2111,7 @@ static void rk628_bt1120_remove(struct i2c_client *client)
|
||||
rk628_control_assert(bt1120->rk628, RGU_CLK_RX);
|
||||
rk628_control_assert(bt1120->rk628, RGU_VOP);
|
||||
rk628_control_assert(bt1120->rk628, RGU_BT1120DEC);
|
||||
rk628_bt1120_power_off(bt1120);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rk628_bt1120_i2c_id[] = {
|
||||
@@ -2057,6 +2130,7 @@ MODULE_DEVICE_TABLE(of, rk628_bt1120_of_match);
|
||||
static struct i2c_driver rk628_bt1120_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rk628-bt1120-v4l2",
|
||||
.pm = &rk628_bt1120_pm_ops,
|
||||
.of_match_table = of_match_ptr(rk628_bt1120_of_match),
|
||||
},
|
||||
.id_table = rk628_bt1120_i2c_id,
|
||||
|
||||
@@ -1277,14 +1277,14 @@ static int rk628_hdmirx_phy_setup(struct v4l2_subdev *sd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
|
||||
static void rk628_csi_initial(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
struct v4l2_subdev_edid def_edid;
|
||||
u32 mask = SW_OUTPUT_MODE_MASK;
|
||||
u32 val = SW_OUTPUT_MODE(OUTPUT_MODE_CSI);
|
||||
|
||||
/* selete int io function */
|
||||
/* select int io function */
|
||||
rk628_i2c_write(csi->rk628, GRF_GPIO3AB_SEL_CON, 0x30002000);
|
||||
rk628_i2c_write(csi->rk628, GRF_GPIO1AB_SEL_CON, HIWORD_UPDATE(0xf, 11, 8));
|
||||
/* I2S_SCKM0 */
|
||||
@@ -1341,7 +1341,13 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
|
||||
def_edid.edid = edid_init_data;
|
||||
rk628_csi_s_edid(sd, &def_edid);
|
||||
rk628_hdmirx_set_hdcp(csi->rk628, &csi->hdcp, false);
|
||||
}
|
||||
|
||||
static void rk628_csi_initial_setup(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
|
||||
rk628_csi_initial(sd);
|
||||
if (csi->rk628->version >= RK628F_VERSION) {
|
||||
csi->rk628->mipi_timing[0] = rk628f_csi0_mipi;
|
||||
csi->rk628->mipi_timing[1] = rk628f_csi1_mipi;
|
||||
@@ -2627,6 +2633,91 @@ static irqreturn_t plugin_detect_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int rk628_csi_power_on(struct rk628_csi *csi)
|
||||
{
|
||||
clk_prepare_enable(csi->soc_24M);
|
||||
if (csi->enable_gpio) {
|
||||
gpiod_set_value(csi->enable_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
gpiod_set_value(csi->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(csi->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(csi->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (csi->power_gpio) {
|
||||
gpiod_set_value(csi->power_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk628_csi_power_off(struct rk628_csi *csi)
|
||||
{
|
||||
if (csi->enable_gpio) {
|
||||
gpiod_set_value(csi->enable_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
gpiod_set_value(csi->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(csi->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(csi->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (csi->power_gpio) {
|
||||
gpiod_set_value(csi->power_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
clk_disable_unprepare(csi->soc_24M);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk628_csi_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
|
||||
v4l2_info(sd, "%s: resume!\n", __func__);
|
||||
|
||||
rk628_csi_power_on(csi);
|
||||
rk628_cru_initialize(csi->rk628);
|
||||
rk628_csi_initial(sd);
|
||||
rk628_hdmirx_plugout(sd);
|
||||
enable_irq(csi->hdmirx_irq);
|
||||
schedule_delayed_work(&csi->delayed_work_enable_hotplug,
|
||||
msecs_to_jiffies(500));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk628_csi_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
|
||||
v4l2_info(sd, "%s: suspend!\n", __func__);
|
||||
|
||||
disable_irq(csi->hdmirx_irq);
|
||||
cancel_delayed_work_sync(&csi->delayed_work_res_change);
|
||||
cancel_delayed_work_sync(&csi->delayed_work_enable_hotplug);
|
||||
rk628_hdmirx_audio_cancel_work_audio(csi->audio_info, true);
|
||||
rk628_csi_power_off(csi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops rk628_csi_pm_ops = {
|
||||
.suspend = rk628_csi_suspend,
|
||||
.resume = rk628_csi_resume,
|
||||
};
|
||||
|
||||
static int rk628_csi_probe_of(struct rk628_csi *csi)
|
||||
{
|
||||
struct device *dev = csi->dev;
|
||||
@@ -2644,28 +2735,27 @@ static int rk628_csi_probe_of(struct rk628_csi *csi)
|
||||
ret = PTR_ERR(csi->soc_24M);
|
||||
dev_err(dev, "Unable to get soc_24M: %d\n", ret);
|
||||
}
|
||||
clk_prepare_enable(csi->soc_24M);
|
||||
|
||||
csi->enable_gpio = devm_gpiod_get_optional(dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(csi->enable_gpio)) {
|
||||
ret = PTR_ERR(csi->enable_gpio);
|
||||
dev_err(dev, "failed to request enable GPIO: %d\n", ret);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
csi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(csi->reset_gpio)) {
|
||||
ret = PTR_ERR(csi->reset_gpio);
|
||||
dev_err(dev, "failed to request reset GPIO: %d\n", ret);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
csi->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(csi->power_gpio)) {
|
||||
dev_err(dev, "failed to get power gpio\n");
|
||||
ret = PTR_ERR(csi->power_gpio);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
csi->plugin_det_gpio = devm_gpiod_get_optional(dev, "plugin-det",
|
||||
@@ -2673,26 +2763,10 @@ static int rk628_csi_probe_of(struct rk628_csi *csi)
|
||||
if (IS_ERR(csi->plugin_det_gpio)) {
|
||||
dev_err(dev, "failed to get hdmirx det gpio\n");
|
||||
ret = PTR_ERR(csi->plugin_det_gpio);
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
csi->rk628->hdmirx_det_gpio = csi->plugin_det_gpio;
|
||||
|
||||
if (csi->enable_gpio) {
|
||||
gpiod_set_value(csi->enable_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
gpiod_set_value(csi->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(csi->reset_gpio, 1);
|
||||
usleep_range(10000, 11000);
|
||||
gpiod_set_value(csi->reset_gpio, 0);
|
||||
usleep_range(10000, 11000);
|
||||
|
||||
if (csi->power_gpio) {
|
||||
gpiod_set_value(csi->power_gpio, 1);
|
||||
usleep_range(500, 510);
|
||||
}
|
||||
|
||||
if (of_property_read_bool(dev->of_node, "hdcp-enable"))
|
||||
hdcp1x_enable = true;
|
||||
|
||||
@@ -2719,7 +2793,7 @@ static int rk628_csi_probe_of(struct rk628_csi *csi)
|
||||
if (!ep) {
|
||||
dev_err(dev, "missing endpoint node\n");
|
||||
ret = -EINVAL;
|
||||
goto clk_put;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
|
||||
@@ -2754,8 +2828,6 @@ free_endpoint:
|
||||
v4l2_fwnode_endpoint_free(&endpoint);
|
||||
put_node:
|
||||
of_node_put(ep);
|
||||
clk_put:
|
||||
clk_disable_unprepare(csi->soc_24M);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2912,6 +2984,7 @@ static int rk628_csi_probe(struct i2c_client *client,
|
||||
return err;
|
||||
}
|
||||
|
||||
rk628_csi_power_on(csi);
|
||||
rk628_cru_initialize(csi->rk628);
|
||||
|
||||
rk628_version_parse(rk628);
|
||||
@@ -2922,14 +2995,15 @@ static int rk628_csi_probe(struct i2c_client *client,
|
||||
v4l2_info(sd, "get multi dev info failed, not use dual mipi mode\n");
|
||||
}
|
||||
|
||||
v4l2_subdev_init(sd, &rk628_csi_ops);
|
||||
v4l2_i2c_subdev_init(sd, client, &rk628_csi_ops);
|
||||
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
|
||||
|
||||
/* i2c access, read chip id*/
|
||||
err = rk628_i2c_read(csi->rk628, CSITX_CSITX_VERSION, &val);
|
||||
if (err) {
|
||||
v4l2_err(sd, "i2c access failed! err:%d\n", err);
|
||||
return -ENODEV;
|
||||
err = -ENODEV;
|
||||
goto power_off;
|
||||
}
|
||||
v4l2_dbg(1, debug, sd, "CSITX VERSION: %#x\n", val);
|
||||
|
||||
@@ -2937,7 +3011,8 @@ static int rk628_csi_probe(struct i2c_client *client,
|
||||
err = rk628_i2c_read(csi->rk628, CSITX1_CSITX_VERSION, &val);
|
||||
if (err) {
|
||||
v4l2_err(sd, "i2c access failed! err:%d\n", err);
|
||||
return -ENODEV;
|
||||
err = -ENODEV;
|
||||
goto power_off;
|
||||
}
|
||||
v4l2_dbg(1, debug, sd, "CSITX1 VERSION: %#x\n", val);
|
||||
}
|
||||
@@ -2947,7 +3022,8 @@ static int rk628_csi_probe(struct i2c_client *client,
|
||||
csi->txphy = rk628_txphy_register(rk628);
|
||||
if (!csi->txphy) {
|
||||
v4l2_err(sd, "register txphy failed\n");
|
||||
return -ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto power_off;
|
||||
}
|
||||
|
||||
/* control handlers */
|
||||
@@ -3095,6 +3171,9 @@ err_hdl:
|
||||
mutex_destroy(&csi->confctl_mutex);
|
||||
media_entity_cleanup(&sd->entity);
|
||||
v4l2_ctrl_handler_free(&csi->hdl);
|
||||
power_off:
|
||||
rk628_csi_power_off(csi);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -3136,6 +3215,7 @@ static int rk628_csi_remove(struct i2c_client *client)
|
||||
rk628_control_assert(csi->rk628, RGU_CSI);
|
||||
if (csi->rk628->version >= RK628F_VERSION)
|
||||
rk628_control_assert(csi->rk628, RGU_CSI1);
|
||||
rk628_csi_power_off(csi);
|
||||
#if KERNEL_VERSION(6, 1, 0) > LINUX_VERSION_CODE
|
||||
return 0;
|
||||
#endif
|
||||
@@ -3144,6 +3224,7 @@ static int rk628_csi_remove(struct i2c_client *client)
|
||||
static struct i2c_driver rk628_csi_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "rk628-csi-v4l2",
|
||||
.pm = &rk628_csi_pm_ops,
|
||||
.of_match_table = of_match_ptr(rk628_csi_of_match),
|
||||
},
|
||||
.id_table = rk628_csi_i2c_id,
|
||||
|
||||
@@ -1835,6 +1835,52 @@ RDBK_TOISP_UNMATCH:
|
||||
spin_unlock_irqrestore(&dev->hdr_lock, flags);
|
||||
}
|
||||
|
||||
static void rkcif_get_other_dev_update_frame_addr(struct rkcif_stream *stream,
|
||||
int dev_idx,
|
||||
u32 *frm_addr_y,
|
||||
u32 *frm_addr_uv)
|
||||
{
|
||||
struct v4l2_mbus_config *mbus_cfg = &stream->cifdev->active_sensor->mbus;
|
||||
u32 intstat = stream->cifdev->other_intstat[dev_idx];
|
||||
int frame_phase = 0;
|
||||
|
||||
switch (stream->id) {
|
||||
case RKCIF_STREAM_MIPI_ID0:
|
||||
frame_phase = SW_FRM_END_ID0(intstat);
|
||||
break;
|
||||
case RKCIF_STREAM_MIPI_ID1:
|
||||
frame_phase = SW_FRM_END_ID1(intstat);
|
||||
break;
|
||||
case RKCIF_STREAM_MIPI_ID2:
|
||||
frame_phase = SW_FRM_END_ID2(intstat);
|
||||
break;
|
||||
case RKCIF_STREAM_MIPI_ID3:
|
||||
frame_phase = SW_FRM_END_ID3(intstat);
|
||||
break;
|
||||
}
|
||||
|
||||
if (frame_phase == 0)
|
||||
return;
|
||||
|
||||
if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CSI2_CPHY ||
|
||||
mbus_cfg->type == V4L2_MBUS_CCP2) {
|
||||
*frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_reg_index_of_frm0_y_addr(stream->id) :
|
||||
get_reg_index_of_frm1_y_addr(stream->id);
|
||||
*frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_reg_index_of_frm0_uv_addr(stream->id) :
|
||||
get_reg_index_of_frm1_uv_addr(stream->id);
|
||||
} else {
|
||||
*frm_addr_y = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_dvp_reg_index_of_frm0_y_addr(stream->id) :
|
||||
get_dvp_reg_index_of_frm1_y_addr(stream->id);
|
||||
*frm_addr_uv = frame_phase & CIF_CSI_FRAME0_READY ?
|
||||
get_dvp_reg_index_of_frm0_uv_addr(stream->id) :
|
||||
get_dvp_reg_index_of_frm1_uv_addr(stream->id);
|
||||
}
|
||||
}
|
||||
|
||||
static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream,
|
||||
u32 frm_addr_y, u32 frm_addr_uv,
|
||||
u32 buff_addr_y, u32 buff_addr_cbcr,
|
||||
@@ -1846,8 +1892,11 @@ static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream,
|
||||
int addr_offset = 0;
|
||||
int i = 0;
|
||||
int tmp_host_index = dev->csi_host_idx;
|
||||
u32 tmp_frm_addr_y, tmp_frm_addr_uv;
|
||||
|
||||
for (i = 0; i < capture_info->multi_dev.dev_num; i++) {
|
||||
tmp_frm_addr_y = frm_addr_y;
|
||||
tmp_frm_addr_uv = frm_addr_uv;
|
||||
if (is_dummy_buf) {
|
||||
addr_y = buff_addr_y;
|
||||
} else {
|
||||
@@ -1855,7 +1904,11 @@ static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream,
|
||||
addr_y = buff_addr_y + addr_offset * i;
|
||||
}
|
||||
dev->csi_host_idx = capture_info->multi_dev.dev_idx[i];
|
||||
rkcif_write_register(dev, frm_addr_y, addr_y);
|
||||
if (i < capture_info->multi_dev.dev_num - 1)
|
||||
rkcif_get_other_dev_update_frame_addr(stream, i,
|
||||
&tmp_frm_addr_y,
|
||||
&tmp_frm_addr_uv);
|
||||
rkcif_write_register(dev, tmp_frm_addr_y, addr_y);
|
||||
if (stream->cif_fmt_out->fmt_type != CIF_FMT_TYPE_RAW &&
|
||||
frm_addr_uv && buff_addr_cbcr) {
|
||||
if (is_dummy_buf) {
|
||||
@@ -1864,7 +1917,7 @@ static void rkcif_write_buff_addr_multi_dev_combine(struct rkcif_stream *stream,
|
||||
addr_offset = dev->channels[stream->id].left_virtual_width;
|
||||
addr_cbcr = buff_addr_cbcr + addr_offset * i;
|
||||
}
|
||||
rkcif_write_register(dev, frm_addr_uv, addr_cbcr);
|
||||
rkcif_write_register(dev, tmp_frm_addr_uv, addr_cbcr);
|
||||
}
|
||||
}
|
||||
dev->csi_host_idx = tmp_host_index;
|
||||
@@ -4939,12 +4992,26 @@ static void rkcif_do_cru_reset(struct rkcif_device *dev)
|
||||
|
||||
void rkcif_do_soft_reset(struct rkcif_device *dev)
|
||||
{
|
||||
struct csi_channel_info *channel = &dev->channels[0];
|
||||
int tmp_csi_host_idx = 0;
|
||||
int i = 0;
|
||||
|
||||
if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY ||
|
||||
dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_CPHY ||
|
||||
dev->active_sensor->mbus.type == V4L2_MBUS_CCP2)
|
||||
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
else
|
||||
dev->active_sensor->mbus.type == V4L2_MBUS_CCP2) {
|
||||
if (channel->capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
tmp_csi_host_idx = dev->csi_host_idx;
|
||||
for (i = 0; i < channel->capture_info.multi_dev.dev_num; i++) {
|
||||
dev->csi_host_idx = channel->capture_info.multi_dev.dev_idx[i];
|
||||
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
}
|
||||
dev->csi_host_idx = tmp_csi_host_idx;
|
||||
} else {
|
||||
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
}
|
||||
} else {
|
||||
rkcif_write_register_or(dev, CIF_REG_DVP_CTRL, 0x000A0000);
|
||||
}
|
||||
usleep_range(10, 20);
|
||||
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev,
|
||||
"vicap do soft reset 0x%x\n", 0x000A0000);
|
||||
@@ -5044,6 +5111,7 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream,
|
||||
struct rkcif_buffer *buf = NULL;
|
||||
int ret;
|
||||
struct rkcif_hw *hw_dev = dev->hw_dev;
|
||||
struct rkmodule_capture_info *capture_info = &dev->channels[0].capture_info;
|
||||
bool can_reset = true;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
@@ -5186,6 +5254,10 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream,
|
||||
if (dev->can_be_reset && dev->chip_id >= CHIP_RK3588_CIF) {
|
||||
rkcif_do_soft_reset(dev);
|
||||
atomic_set(&dev->streamoff_cnt, 0);
|
||||
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
for (i = 0; i < capture_info->multi_dev.dev_num - 1; i++)
|
||||
dev->other_intstat[i] = 0;
|
||||
}
|
||||
}
|
||||
if (dev->can_be_reset && can_reset) {
|
||||
dev->can_be_reset = false;
|
||||
@@ -11302,17 +11374,39 @@ static void rkcif_check_mipi_interlaced_frame_id(struct rkcif_stream *stream)
|
||||
stream->last_fs_interlaced_phase = fs_interlaced_phase;
|
||||
}
|
||||
|
||||
static void rkcif_save_other_intstat_with_combine_mode(struct rkcif_device *cif_dev)
|
||||
{
|
||||
struct rkmodule_capture_info *capture_info = &cif_dev->channels[0].capture_info;
|
||||
int i = 0;
|
||||
int tmp_csi_host = 0;
|
||||
|
||||
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
tmp_csi_host = cif_dev->csi_host_idx;
|
||||
for (i = 0; i < capture_info->multi_dev.dev_num - 1; i++) {
|
||||
cif_dev->csi_host_idx = capture_info->multi_dev.dev_idx[i];
|
||||
cif_dev->other_intstat[i] = rkcif_read_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT);
|
||||
if (cif_dev->other_intstat[i])
|
||||
rkcif_write_register(cif_dev,
|
||||
CIF_REG_MIPI_LVDS_INTSTAT,
|
||||
cif_dev->other_intstat[i]);
|
||||
}
|
||||
cif_dev->csi_host_idx = tmp_csi_host;
|
||||
}
|
||||
}
|
||||
|
||||
/* pingpong irq for rk3588 and next */
|
||||
void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
{
|
||||
struct rkcif_stream *stream;
|
||||
struct rkcif_stream *detect_stream = &cif_dev->stream[0];
|
||||
struct v4l2_mbus_config *mbus;
|
||||
struct csi_channel_info *channel = &cif_dev->channels[0];
|
||||
unsigned int intstat, i = 0xff;
|
||||
unsigned long flags;
|
||||
bool is_update = false;
|
||||
int ret = 0;
|
||||
int on = 0;
|
||||
int tmp_csi_host_idx = 0;
|
||||
|
||||
if (!cif_dev->active_sensor)
|
||||
return;
|
||||
@@ -11329,6 +11423,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
cif_dev->err_state_work.lastline = lastline;
|
||||
cif_dev->err_state_work.intstat = intstat;
|
||||
|
||||
rkcif_save_other_intstat_with_combine_mode(cif_dev);
|
||||
/* clear all interrupts that has been triggered */
|
||||
if (intstat) {
|
||||
rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT, intstat);
|
||||
@@ -11351,7 +11446,16 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
|
||||
}
|
||||
cif_dev->irq_stats.csi_size_err_cnt++;
|
||||
cif_dev->err_state |= RKCIF_ERR_SIZE;
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
if (cif_dev->channels[0].capture_info.mode == RKMODULE_MULTI_DEV_COMBINE_ONE) {
|
||||
tmp_csi_host_idx = cif_dev->csi_host_idx;
|
||||
for (i = 0; i < channel->capture_info.multi_dev.dev_num; i++) {
|
||||
cif_dev->csi_host_idx = channel->capture_info.multi_dev.dev_idx[i];
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
}
|
||||
cif_dev->csi_host_idx = tmp_csi_host_idx;
|
||||
} else {
|
||||
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_CTRL, 0x000A0000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -939,6 +939,7 @@ struct rkcif_device {
|
||||
int sensor_state;
|
||||
u32 intr_mask;
|
||||
struct delayed_work work_deal_err;
|
||||
u32 other_intstat[RKMODULE_MULTI_DEV_NUM];
|
||||
};
|
||||
|
||||
extern struct platform_driver rkcif_plat_drv;
|
||||
|
||||
@@ -672,49 +672,56 @@ static bool rk628_display_route_check(struct rk628 *rk628)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rk628_final_display_route(struct rk628 *rk628)
|
||||
static void rk628_current_display_route(struct rk628 *rk628, char *input_s,
|
||||
int input_s_len, char *output_s,
|
||||
int output_s_len)
|
||||
{
|
||||
char *input = NULL;
|
||||
char *output = NULL;
|
||||
char buf[20];
|
||||
*input_s = '\0';
|
||||
*output_s = '\0';
|
||||
|
||||
if (rk628_input_is_hdmi(rk628))
|
||||
input = "hdmi";
|
||||
if (rk628_input_is_rgb(rk628))
|
||||
strlcat(input_s, "RGB", input_s_len);
|
||||
else if (rk628_input_is_bt1120(rk628))
|
||||
input = "bt1120";
|
||||
strlcat(input_s, "BT1120", input_s_len);
|
||||
else if (rk628_input_is_hdmi(rk628))
|
||||
strlcat(input_s, "HDMI", input_s_len);
|
||||
else
|
||||
input = "rgb";
|
||||
strlcat(input_s, "unknown", input_s_len);
|
||||
|
||||
if (rk628_output_is_rgb(rk628))
|
||||
strlcat(output_s, "RGB ", output_s_len);
|
||||
|
||||
if (rk628_output_is_bt1120(rk628))
|
||||
strlcat(output_s, "BT1120 ", output_s_len);
|
||||
|
||||
if (rk628_output_is_gvi(rk628))
|
||||
output = "gvi";
|
||||
else if (rk628_output_is_lvds(rk628))
|
||||
output = "lvds";
|
||||
else if (rk628_output_is_dsi(rk628))
|
||||
output = "dsi";
|
||||
else if (rk628_output_is_csi(rk628))
|
||||
output = "csi";
|
||||
strlcat(output_s, "GVI ", output_s_len);
|
||||
|
||||
if (rk628_output_is_bt1120(rk628)) {
|
||||
if (output)
|
||||
sprintf(buf, "%s & %s", output, "bt1120");
|
||||
else
|
||||
output = "bt1120";
|
||||
} else if (rk628_output_is_rgb(rk628)) {
|
||||
if (output)
|
||||
sprintf(buf, "%s & %s", output, "rgb");
|
||||
else
|
||||
output = "rgb";
|
||||
}
|
||||
if (rk628_output_is_lvds(rk628))
|
||||
strncat(output_s, "LVDS ", output_s_len);
|
||||
|
||||
if (rk628_output_is_hdmi(rk628)) {
|
||||
if (output)
|
||||
sprintf(buf, "%s & %s", output, "hdmi");
|
||||
else
|
||||
output = "hdmi";
|
||||
}
|
||||
if (rk628_output_is_dsi(rk628))
|
||||
strlcat(output_s, "DSI ", output_s_len);
|
||||
|
||||
dev_info(rk628->dev, "input_mode:%s output_mode:%s\n", input,
|
||||
hweight32(rk628->output_mode) > 1 ? buf : output);
|
||||
if (rk628_output_is_csi(rk628))
|
||||
strlcat(output_s, "CSI ", output_s_len);
|
||||
|
||||
if (rk628_output_is_hdmi(rk628))
|
||||
strlcat(output_s, "HDMI ", output_s_len);
|
||||
|
||||
if (!strlen(output_s))
|
||||
strlcat(output_s, "unknown", output_s_len);
|
||||
}
|
||||
|
||||
static void rk628_show_current_display_route(struct rk628 *rk628)
|
||||
{
|
||||
char input_s[10], output_s[30];
|
||||
|
||||
rk628_current_display_route(rk628, input_s, sizeof(input_s),
|
||||
output_s, sizeof(output_s));
|
||||
|
||||
dev_info(rk628->dev, "input_mode: %s, output_mode: %s\n", input_s,
|
||||
output_s);
|
||||
}
|
||||
|
||||
static int rk628_display_route_info_parse(struct rk628 *rk628)
|
||||
@@ -723,40 +730,50 @@ static int rk628_display_route_info_parse(struct rk628 *rk628)
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) {
|
||||
if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-in") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) {
|
||||
rk628->input_mode = BIT(INPUT_MODE_HDMI);
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) {
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb-in") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) {
|
||||
rk628->input_mode = BIT(INPUT_MODE_RGB);
|
||||
ret = rk628_rgb_parse(rk628, NULL);
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) {
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120-in") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) {
|
||||
rk628->input_mode = BIT(INPUT_MODE_BT1120);
|
||||
ret = rk628_rgb_parse(rk628, NULL);
|
||||
} else {
|
||||
rk628->input_mode = BIT(INPUT_MODE_RGB);
|
||||
}
|
||||
|
||||
if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi"))) {
|
||||
if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi-out")) ||
|
||||
(np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi"))) {
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_GVI);
|
||||
ret = rk628_gvi_parse(rk628, np);
|
||||
} else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds"))) {
|
||||
} else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds-out")) ||
|
||||
(np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds"))) {
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_LVDS);
|
||||
ret = rk628_lvds_parse(rk628, np);
|
||||
} else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi"))) {
|
||||
} else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi-out")) ||
|
||||
(np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi"))) {
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_DSI);
|
||||
ret = rk628_dsi_parse(rk628, np);
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) {
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628-csi-out") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) {
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_CSI);
|
||||
}
|
||||
if (np)
|
||||
of_node_put(np);
|
||||
|
||||
if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out"))
|
||||
if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-out") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out"))
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_HDMI);
|
||||
|
||||
if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) {
|
||||
if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb-out") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) {
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_RGB);
|
||||
ret = rk628_rgb_parse(rk628, NULL);
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) {
|
||||
} else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120-out") ||
|
||||
of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) {
|
||||
rk628->output_mode |= BIT(OUTPUT_MODE_BT1120);
|
||||
ret = rk628_rgb_parse(rk628, NULL);
|
||||
}
|
||||
@@ -879,25 +896,6 @@ static int rk628_display_timings_get(struct rk628 *rk628)
|
||||
pr_info(args); \
|
||||
} while (0)
|
||||
|
||||
static void rk628_show_input_mode(struct seq_file *s)
|
||||
{
|
||||
struct rk628 *rk628 = s->private;
|
||||
char input_s[10] = {0};
|
||||
|
||||
/* show input mode */
|
||||
if (rk628_input_is_hdmi(rk628))
|
||||
strcpy(input_s, "HDMI");
|
||||
else if (rk628_input_is_bt1120(rk628))
|
||||
strcpy(input_s, "BT1120");
|
||||
else if (rk628_input_is_rgb(rk628))
|
||||
strcpy(input_s, "RGB");
|
||||
|
||||
if (!strlen(input_s))
|
||||
strcpy(input_s, "unknown ");
|
||||
|
||||
DEBUG_PRINT("input: %s\n", input_s);
|
||||
}
|
||||
|
||||
static void rk628_show_resolution(struct seq_file *s)
|
||||
{
|
||||
struct rk628 *rk628 = s->private;
|
||||
@@ -995,38 +993,6 @@ static void rk628_show_input_resolution(struct seq_file *s)
|
||||
rk628_show_resolution(s);
|
||||
}
|
||||
|
||||
static void rk628_show_output_mode(struct seq_file *s)
|
||||
{
|
||||
struct rk628 *rk628 = s->private;
|
||||
char output_s[30] = {0};
|
||||
char *p = output_s;
|
||||
|
||||
if (rk628_output_is_gvi(rk628))
|
||||
strcpy(p, "GVI ");
|
||||
else if (rk628_output_is_lvds(rk628))
|
||||
strcpy(p, "LVDS ");
|
||||
else if (rk628_output_is_dsi(rk628))
|
||||
strcpy(p, "DSI ");
|
||||
else if (rk628_output_is_csi(rk628))
|
||||
strcpy(p, "CSI ");
|
||||
p += strlen(p);
|
||||
|
||||
if (rk628_output_is_hdmi(rk628)) {
|
||||
strcpy(p, "HDMI ");
|
||||
p += strlen(p);
|
||||
}
|
||||
|
||||
if (rk628_output_is_rgb(rk628))
|
||||
strcpy(p, "RGB ");
|
||||
else if (rk628_output_is_bt1120(rk628))
|
||||
strcpy(p, "BT1120 ");
|
||||
|
||||
if (!strlen(output_s))
|
||||
strcpy(p, "unknown ");
|
||||
|
||||
DEBUG_PRINT("output: %s\n", output_s);
|
||||
}
|
||||
|
||||
static void rk628_show_output_resolution(struct seq_file *s)
|
||||
{
|
||||
struct rk628 *rk628 = s->private;
|
||||
@@ -1137,16 +1103,20 @@ static void rk628_show_csc_info(struct seq_file *s)
|
||||
static int rk628_debugfs_dump(struct seq_file *s, void *data)
|
||||
{
|
||||
struct rk628 *rk628 = s->private;
|
||||
char input_s[10], output_s[30];
|
||||
u32 val;
|
||||
int sw_hsync_pol, sw_vsync_pol;
|
||||
u32 dsp_frame_v_start, dsp_frame_h_start;
|
||||
|
||||
rk628_current_display_route(rk628, input_s, sizeof(input_s),
|
||||
output_s, sizeof(output_s));
|
||||
|
||||
/* show input info */
|
||||
rk628_show_input_mode(s);
|
||||
DEBUG_PRINT("input: %s\n", input_s);
|
||||
rk628_show_input_resolution(s);
|
||||
|
||||
/* show output info */
|
||||
rk628_show_output_mode(s);
|
||||
DEBUG_PRINT("output: %s\n", output_s);
|
||||
rk628_show_output_resolution(s);
|
||||
|
||||
/* show csc info */
|
||||
@@ -1443,13 +1413,14 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
|
||||
rk628_show_current_display_route(rk628);
|
||||
|
||||
if (!rk628_display_route_check(rk628)) {
|
||||
dev_err(dev, "display route check err\n");
|
||||
ret = -EINVAL;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
rk628_final_display_route(rk628);
|
||||
rk628_pwr_consumption_init(rk628);
|
||||
|
||||
#ifdef CONFIG_FB
|
||||
|
||||
@@ -830,7 +830,10 @@ static u32 rk628_dsi_get_lane_rate(const struct rk628_dsi *dsi)
|
||||
u32 max_lane_rate = 1500;
|
||||
u8 bpp, lanes;
|
||||
|
||||
dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, "rk628-dsi");
|
||||
dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, "rk628-dsi-out");
|
||||
if (!dsi_np)
|
||||
dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node,
|
||||
"rk628-dsi");
|
||||
if (dsi_np && !of_property_read_u32(dsi_np, "rockchip,lane-mbps", &value)) {
|
||||
lane_rate = value;
|
||||
} else {
|
||||
|
||||
@@ -200,6 +200,9 @@ rockchip_ipa_get_static_power(struct ipa_power_model_data *data,
|
||||
int temp;
|
||||
int ret;
|
||||
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
ret = data->tz->ops->get_temp(data->tz, &temp);
|
||||
if (ret) {
|
||||
pr_err("%s:failed to read %s temp\n",
|
||||
|
||||
@@ -994,7 +994,7 @@ static int av1dec_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
mpp = &dec->mpp;
|
||||
platform_set_drvdata(pdev, dec);
|
||||
platform_set_drvdata(pdev, mpp);
|
||||
|
||||
if (pdev->dev.of_node) {
|
||||
match = of_match_node(mpp_av1dec_dt_match, pdev->dev.of_node);
|
||||
@@ -1042,39 +1042,19 @@ failed_get_irq:
|
||||
static int av1dec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct av1dec_dev *dec = platform_get_drvdata(pdev);
|
||||
struct mpp_dev *mpp = platform_get_drvdata(pdev);
|
||||
|
||||
dev_info(dev, "remove device\n");
|
||||
mpp_dev_remove(&dec->mpp);
|
||||
av1dec_procfs_remove(&dec->mpp);
|
||||
mpp_dev_remove(mpp);
|
||||
av1dec_procfs_remove(mpp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void av1dec_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
int val;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct av1dec_dev *dec = platform_get_drvdata(pdev);
|
||||
struct mpp_dev *mpp = &dec->mpp;
|
||||
|
||||
dev_info(dev, "shutdown device\n");
|
||||
|
||||
atomic_inc(&mpp->srv->shutdown_request);
|
||||
ret = readx_poll_timeout(atomic_read,
|
||||
&mpp->task_count,
|
||||
val, val == 0, 1000, 200000);
|
||||
if (ret == -ETIMEDOUT)
|
||||
dev_err(dev, "wait total running time out\n");
|
||||
|
||||
dev_info(dev, "shutdown success\n");
|
||||
}
|
||||
|
||||
struct platform_driver rockchip_av1dec_driver = {
|
||||
.probe = av1dec_probe,
|
||||
.remove = av1dec_remove,
|
||||
.shutdown = av1dec_shutdown,
|
||||
.shutdown = mpp_dev_shutdown,
|
||||
.driver = {
|
||||
.name = AV1DEC_DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(mpp_av1dec_dt_match),
|
||||
|
||||
@@ -325,8 +325,8 @@ static int devfreq_target(struct device *dev,
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned long target_volt, target_freq;
|
||||
unsigned long aclk_rate_hz, core_rate_hz, cabac_rate_hz;
|
||||
|
||||
struct rkvdec_dev *dec = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
|
||||
struct devfreq *devfreq = dec->devfreq;
|
||||
struct devfreq_dev_status *stat = &devfreq->last_status;
|
||||
unsigned long old_clk_rate = stat->current_frequency;
|
||||
@@ -392,7 +392,8 @@ static int devfreq_target(struct device *dev,
|
||||
static int devfreq_get_cur_freq(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
struct rkvdec_dev *dec = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
|
||||
|
||||
*freq = clk_get_rate(dec->aclk_info.clk);
|
||||
|
||||
@@ -402,7 +403,8 @@ static int devfreq_get_cur_freq(struct device *dev,
|
||||
static int devfreq_get_dev_status(struct device *dev,
|
||||
struct devfreq_dev_status *stat)
|
||||
{
|
||||
struct rkvdec_dev *dec = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
|
||||
struct devfreq *devfreq = dec->devfreq;
|
||||
|
||||
memcpy(stat, &devfreq->last_status, sizeof(*stat));
|
||||
@@ -1904,11 +1906,11 @@ static int rkvdec_probe(struct platform_device *pdev)
|
||||
static int rkvdec_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rkvdec_dev *dec = platform_get_drvdata(pdev);
|
||||
struct mpp_dev *mpp = platform_get_drvdata(pdev);
|
||||
|
||||
dev_info(dev, "remove device\n");
|
||||
mpp_dev_remove(&dec->mpp);
|
||||
rkvdec_procfs_remove(&dec->mpp);
|
||||
mpp_dev_remove(mpp);
|
||||
rkvdec_procfs_remove(mpp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -711,8 +711,8 @@ static int rkvdec2_devfreq_target(struct device *dev,
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned long target_volt, target_freq;
|
||||
int ret = 0;
|
||||
|
||||
struct rkvdec2_dev *dec = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
|
||||
struct devfreq *devfreq = dec->devfreq;
|
||||
struct devfreq_dev_status *stat = &devfreq->last_status;
|
||||
unsigned long old_clk_rate = stat->current_frequency;
|
||||
@@ -774,7 +774,8 @@ static int rkvdec2_devfreq_get_dev_status(struct device *dev,
|
||||
static int rkvdec2_devfreq_get_cur_freq(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
struct rkvdec2_dev *dec = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp);
|
||||
|
||||
*freq = dec->core_last_rate_hz;
|
||||
|
||||
|
||||
@@ -850,8 +850,8 @@ static int rkvenc_devfreq_target(struct device *dev,
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned long target_volt, target_freq;
|
||||
int ret = 0;
|
||||
|
||||
struct rkvenc_dev *enc = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
|
||||
struct devfreq *devfreq = enc->devfreq;
|
||||
struct devfreq_dev_status *stat = &devfreq->last_status;
|
||||
unsigned long old_clk_rate = stat->current_frequency;
|
||||
@@ -913,7 +913,8 @@ static int rkvenc_devfreq_get_dev_status(struct device *dev,
|
||||
static int rkvenc_devfreq_get_cur_freq(struct device *dev,
|
||||
unsigned long *freq)
|
||||
{
|
||||
struct rkvenc_dev *enc = dev_get_drvdata(dev);
|
||||
struct mpp_dev *mpp = dev_get_drvdata(dev);
|
||||
struct rkvenc_dev *enc = to_rkvenc_dev(mpp);
|
||||
|
||||
*freq = enc->core_last_rate_hz;
|
||||
|
||||
|
||||
@@ -696,9 +696,8 @@ static int vdpp_probe(struct platform_device *pdev)
|
||||
vdpp = devm_kzalloc(dev, sizeof(struct vdpp_dev), GFP_KERNEL);
|
||||
if (!vdpp)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, vdpp);
|
||||
|
||||
mpp = &vdpp->mpp;
|
||||
platform_set_drvdata(pdev, mpp);
|
||||
if (pdev->dev.of_node) {
|
||||
match = of_match_node(mpp_vdpp_dt_match, pdev->dev.of_node);
|
||||
if (match)
|
||||
@@ -745,37 +744,19 @@ static int vdpp_probe(struct platform_device *pdev)
|
||||
static int vdpp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct vdpp_dev *vdpp = platform_get_drvdata(pdev);
|
||||
struct mpp_dev *mpp = platform_get_drvdata(pdev);
|
||||
|
||||
dev_info(dev, "remove device\n");
|
||||
mpp_dev_remove(&vdpp->mpp);
|
||||
vdpp_procfs_remove(&vdpp->mpp);
|
||||
mpp_dev_remove(mpp);
|
||||
vdpp_procfs_remove(mpp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vdpp_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
int val;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct vdpp_dev *vdpp = platform_get_drvdata(pdev);
|
||||
struct mpp_dev *mpp = &vdpp->mpp;
|
||||
|
||||
dev_info(dev, "shutdown device\n");
|
||||
|
||||
atomic_inc(&mpp->srv->shutdown_request);
|
||||
ret = readx_poll_timeout(atomic_read,
|
||||
&mpp->task_count,
|
||||
val, val == 0, 20000, 200000);
|
||||
if (ret == -ETIMEDOUT)
|
||||
dev_err(dev, "wait total running time out\n");
|
||||
}
|
||||
|
||||
struct platform_driver rockchip_vdpp_driver = {
|
||||
.probe = vdpp_probe,
|
||||
.remove = vdpp_remove,
|
||||
.shutdown = vdpp_shutdown,
|
||||
.shutdown = mpp_dev_shutdown,
|
||||
.driver = {
|
||||
.name = VDPP_DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(mpp_vdpp_dt_match),
|
||||
|
||||
@@ -231,16 +231,22 @@ static int rk817_codec_ctl_gpio(struct rk817_codec_priv *rk817,
|
||||
{
|
||||
if ((gpio & CODEC_SET_SPK) &&
|
||||
rk817->spk_ctl_gpio) {
|
||||
if (level && rk817->spk_mute_delay)
|
||||
msleep(rk817->spk_mute_delay);
|
||||
gpiod_set_value(rk817->spk_ctl_gpio, level);
|
||||
DBG("%s set spk clt %d\n", __func__, level);
|
||||
msleep(rk817->spk_mute_delay);
|
||||
if (!level && rk817->spk_mute_delay)
|
||||
msleep(rk817->spk_mute_delay);
|
||||
}
|
||||
|
||||
if ((gpio & CODEC_SET_HP) &&
|
||||
rk817->hp_ctl_gpio) {
|
||||
if (level && rk817->hp_mute_delay)
|
||||
msleep(rk817->hp_mute_delay);
|
||||
gpiod_set_value(rk817->hp_ctl_gpio, level);
|
||||
DBG("%s set hp clt %d\n", __func__, level);
|
||||
msleep(rk817->hp_mute_delay);
|
||||
if (!level && rk817->hp_mute_delay)
|
||||
msleep(rk817->hp_mute_delay);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -260,12 +266,12 @@ static int rk817_reset(struct snd_soc_component *component)
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG5, 0x00);
|
||||
snd_soc_component_write(component, RK817_CODEC_DTOP_DIGEN_CLKE, 0x00);
|
||||
if (rk817->chip_ver <= 0x4) {
|
||||
DBG("%s (%d): SMIC TudorAG and previous versions\n",
|
||||
DBG("%s (%d): 0x4 and previous versions\n",
|
||||
__func__, __LINE__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
|
||||
} else {
|
||||
DBG("%s (%d): SMIC TudorAG version later\n",
|
||||
DBG("%s (%d): 0x4 version later\n",
|
||||
__func__, __LINE__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
|
||||
@@ -275,6 +281,77 @@ static int rk817_reset(struct snd_soc_component *component)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_restart_dac_digital_clk(struct snd_soc_component *component)
|
||||
{
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
|
||||
PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
|
||||
DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
|
||||
PWD_DACBIAS_MASK, PWD_DACBIAS_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_restart_dac_digital_clk_and_apll(struct snd_soc_component *component)
|
||||
{
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
|
||||
PWD_DACBIAS_MASK, PWD_DACBIAS_DOWN);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
|
||||
DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
|
||||
PLL_PW_DOWN, PLL_PW_DOWN);
|
||||
usleep_range(50, 60);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
|
||||
PLL_PW_DOWN, PLL_PW_UP);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_ADAC_CFG1,
|
||||
PWD_DACBIAS_MASK, PWD_DACBIAS_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_restart_adc_digital_clk(struct snd_soc_component *component)
|
||||
{
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
|
||||
DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk817_restart_adc_digital_clk_and_apll(struct snd_soc_component *component)
|
||||
{
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
|
||||
usleep_range(500, 600);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
|
||||
DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
|
||||
PLL_PW_DOWN, PLL_PW_DOWN);
|
||||
usleep_range(50, 60);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
|
||||
PLL_PW_DOWN, PLL_PW_UP);
|
||||
usleep_range(500, 600);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rk817_reg_val_typ playback_power_up_list[] = {
|
||||
{RK817_CODEC_AREF_RTCFG1, 0x40},
|
||||
{RK817_CODEC_DDAC_POPD_DACST, 0x02},
|
||||
@@ -373,22 +450,16 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type)
|
||||
|
||||
/* configure APLL CFG0/4 */
|
||||
if (rk817->chip_ver <= 0x4) {
|
||||
DBG("%s (%d): SMIC TudorAG and previous versions\n",
|
||||
DBG("%s (%d): 0x4 and previous versions\n",
|
||||
__func__, __LINE__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
|
||||
} else {
|
||||
DBG("%s: SMIC TudorAG version later\n", __func__);
|
||||
DBG("%s: 0x4 version later\n", __func__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_MASK, DAC_DIG_CLK_DIS);
|
||||
usleep_range(2000, 2500);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_MASK, DAC_DIG_CLK_EN);
|
||||
DBG("%s: %d - Playback DIG CLK OPS\n", __func__, __LINE__);
|
||||
rk817_restart_dac_digital_clk(component);
|
||||
}
|
||||
|
||||
if (type & RK817_CODEC_CAPTURE) {
|
||||
@@ -404,22 +475,17 @@ static int rk817_codec_power_up(struct snd_soc_component *component, int type)
|
||||
|
||||
/* configure APLL CFG0/4 */
|
||||
if (rk817->chip_ver <= 0x4) {
|
||||
DBG("%s (%d): SMIC TudorAG and previous versions\n",
|
||||
DBG("%s (%d): 0x4 and previous versions\n",
|
||||
__func__, __LINE__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
|
||||
} else {
|
||||
DBG("%s: SMIC TudorAG version later\n", __func__);
|
||||
DBG("%s: 0x4 version later\n", __func__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
|
||||
}
|
||||
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS);
|
||||
usleep_range(2000, 2500);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN);
|
||||
DBG("%s: %d - Capture DIG CLK OPS\n", __func__, __LINE__);
|
||||
rk817_restart_adc_digital_clk(component);
|
||||
|
||||
if (rk817->mic_in_differential)
|
||||
snd_soc_component_update_bits(component,
|
||||
@@ -941,25 +1007,19 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
|
||||
unsigned int rate = params_rate(params);
|
||||
unsigned char apll_cfg3_val;
|
||||
unsigned char dtop_digen_sr_lmt0;
|
||||
unsigned char dtop_digen_clke;
|
||||
|
||||
DBG("%s : sample rate = %dHz\n", __func__, rate);
|
||||
|
||||
if (rk817->chip_ver <= 0x4) {
|
||||
DBG("%s: SMIC TudorAG and previous versions\n", __func__);
|
||||
DBG("%s: 0x4 and previous versions\n", __func__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95);
|
||||
} else {
|
||||
DBG("%s: SMIC TudorAG version later\n", __func__);
|
||||
DBG("%s: 0x4 version later\n", __func__);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04);
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5);
|
||||
}
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
dtop_digen_clke = DAC_DIG_CLK_EN;
|
||||
else
|
||||
dtop_digen_clke = ADC_DIG_CLK_EN;
|
||||
|
||||
switch (rate) {
|
||||
case 8000:
|
||||
apll_cfg3_val = 0x03;
|
||||
@@ -991,19 +1051,12 @@ static int rk817_hw_params(struct snd_pcm_substream *substream,
|
||||
*/
|
||||
if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) {
|
||||
snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val);
|
||||
/* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
dtop_digen_clke, 0x00);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0,
|
||||
DACSRT_MASK, dtop_digen_sr_lmt0);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
dtop_digen_clke, dtop_digen_clke);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
|
||||
PLL_PW_DOWN, PLL_PW_DOWN);
|
||||
usleep_range(50, 60);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5,
|
||||
PLL_PW_DOWN, PLL_PW_UP);
|
||||
usleep_range(500, 600);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
rk817_restart_dac_digital_clk_and_apll(component);
|
||||
else
|
||||
rk817_restart_adc_digital_clk_and_apll(component);
|
||||
}
|
||||
|
||||
switch (params_format(params)) {
|
||||
@@ -1041,14 +1094,7 @@ static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream)
|
||||
snd_soc_component_update_bits(component,
|
||||
RK817_CODEC_DDAC_MUTE_MIXCTL,
|
||||
DACMT_ENABLE, DACMT_ENABLE);
|
||||
snd_soc_component_write(component, RK817_CODEC_ADAC_CFG1,
|
||||
PWD_DACBIAS_DOWN | PWD_DACD_DOWN |
|
||||
PWD_DACL_DOWN | PWD_DACR_DOWN);
|
||||
/* Reset DAC DTOP_DIGEN_CLKE for playback stopped */
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
DAC_DIG_CLK_EN, DAC_DIG_CLK_EN);
|
||||
rk817_restart_dac_digital_clk(component);
|
||||
snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE,
|
||||
I2SRX_EN_MASK, I2SRX_DIS);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user