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:
Tao Huang
2024-02-07 16:32:18 +08:00
28 changed files with 1039 additions and 458 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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"

View File

@@ -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";

View File

@@ -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";

View File

@@ -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;

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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";

View File

@@ -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;

View File

@@ -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;

View File

@@ -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",

View File

@@ -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;

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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 {

View File

@@ -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",

View File

@@ -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),

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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),

View File

@@ -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 {