diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index c7e0b95a5d9d..1c6a631085df 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1226,6 +1226,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3506g-demo-display-control.dtb \ rk3506g-evb1-v10.dtb \ rk3506g-evb1-v10-amp.dtb \ + rk3506g-evb1-v10-dsmc-lb-slave.dtb \ + rk3506g-evb1-v10-dsmc-master.dtb \ rk3506g-evb1-v10-flexbus-adc-dac.dtb \ rk3506g-evb1-v10-mcu-k350c4516t.dtb \ rk3506g-evb1-v10-rgb-Q7050ITH2641AA1T.dtb \ diff --git a/arch/arm/boot/dts/rk3506g-demo-display-control.dts b/arch/arm/boot/dts/rk3506g-demo-display-control.dts index 8e48294eaae7..2140407cee7c 100644 --- a/arch/arm/boot/dts/rk3506g-demo-display-control.dts +++ b/arch/arm/boot/dts/rk3506g-demo-display-control.dts @@ -133,6 +133,31 @@ }; }; + /* Only lineout, no hpout */ + rk730_sound: rk730-sound { + status = "okay"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip-rk730"; + spk-con-gpio = <&gpio4 RK_PB2 GPIO_ACTIVE_HIGH>; + rockchip,pre-power-on-delay-ms = <30>; + rockchip,post-power-down-delay-ms = <40>; + rockchip,format = "i2s"; + rockchip,mclk-fs = <256>; + rockchip,cpu = <&sai1>; + rockchip,codec = <&rk730>; + rockchip,audio-routing = + "Headphone", "LOUT1", + "Headphone", "ROUT1", + "Speaker", "LOUT2", + "Speaker", "ROUT2", + "Headphone", "Headphone Power", + "Headphone", "Headphone Power", + "Speaker", "Speaker Power", + "Speaker", "Speaker Power", + "MIC2", "Main Mic", + "MIC1", "Headset Mic"; + }; + sdio_pwrseq: sdio-pwrseq { compatible = "mmc-pwrseq-simple"; pinctrl-names = "default"; @@ -404,6 +429,18 @@ pinctrl-names = "default"; pinctrl-0 = <&rm_io4_i2c2_scl &rm_io5_i2c2_sda>; + rk730: rk730@17 { + #sound-dai-cells = <0>; + compatible = "rockchip,rk730"; + reg = <0x17>; + clocks = <&mclkout_sai1>; + clock-names = "mclk"; + assigned-clocks = <&mclkout_sai1>; + assigned-clock-rates = <12288000>; + pinctrl-names = "default"; + pinctrl-0 = <&rm_io8_sai1_mclk>; + }; + hym8563: hym8563@51 { compatible = "haoyu,hym8563"; reg = <0x51>; @@ -538,6 +575,15 @@ status = "okay"; }; +&sai1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&rm_io9_sai1_sclk + &rm_io10_sai1_lrck + &rm_io11_sai1_sdi + &rm_io12_sai1_sdo0>; +}; + &saradc { vref-supply = <&vcc_1v8>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3506g-evb1-v10-dsmc-lb-slave.dts b/arch/arm/boot/dts/rk3506g-evb1-v10-dsmc-lb-slave.dts new file mode 100644 index 000000000000..d62a1b9c6baf --- /dev/null +++ b/arch/arm/boot/dts/rk3506g-evb1-v10-dsmc-lb-slave.dts @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rk3506.dtsi" +#include "rk3506-evb1-v10.dtsi" + +/ { + model = "Rockchip RK3506G(QFN128) EVB1 V10 Board + RK EVB Ext RK3506 DSMC to DSMCSLV Convert V10 board + Rockchip RK3506G(QFN128) EVB1 V10 Board"; + compatible = "rockchip,rk3506g-evb1-v10-dsmc-lb-slave", "rockchip,rk3506"; +}; + +&dsmc_lb_slave { + memory-region = <&dsmc_lb_slave_mem>; + status = "okay"; +}; + +&reserved_memory { + dsmc_lb_slave_mem: dsmc-lb-slave-mem@6000000 { + compatible = "rockchip,dsmc-lb-slave-mem"; + reg = <0x6000000 0x2000000>; + }; +}; diff --git a/arch/arm/boot/dts/rk3506g-evb1-v10-dsmc-master.dts b/arch/arm/boot/dts/rk3506g-evb1-v10-dsmc-master.dts new file mode 100644 index 000000000000..468fb110a526 --- /dev/null +++ b/arch/arm/boot/dts/rk3506g-evb1-v10-dsmc-master.dts @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rk3506.dtsi" +#include "rk3506-evb1-v10.dtsi" + +/ { + model = "Rockchip RK3506G(QFN128) EVB1 V10 Board + RK EVB Ext RK3506 DSMC to DSMCSLV Convert V10 board + Rockchip RK3506G(QFN128) EVB1 V10 Board"; + compatible = "rockchip,rk3506g-evb1-v10-dsmc-master", "rockchip,rk3506"; +}; + +&dsmc { + clock-frequency = <100000000>; + status = "okay"; + slave { + rockchip,dqs-dll = <0x20 0x20 + 0x20 0x20 + 0x20 0x20 + 0x20 0x20>; + rockchip,ranges = <0x0 0xc0000000 0x0 0x2000000>; + }; +}; + +&dsmc_slave { + status = "okay"; + lb-slave { + dsmc_lb_slave0: lb-slave0 { + rockchip,int-en = <0x2>; + status = "okay"; + dsmc_p0_region: region { + dsmc_p0_region0: region0 { + status = "okay"; + }; + dsmc_p0_region3: region3 { + status = "okay"; + }; + }; + }; + }; +}; diff --git a/arch/arm/configs/rk3506_defconfig b/arch/arm/configs/rk3506_defconfig index 8af6cc241401..2c0eabcaaca7 100644 --- a/arch/arm/configs/rk3506_defconfig +++ b/arch/arm/configs/rk3506_defconfig @@ -259,6 +259,7 @@ CONFIG_SND_SOC_ES7202=y CONFIG_SND_SOC_ES7202_MIC_MAX_CHANNELS=8 CONFIG_SND_SOC_ES8323=y CONFIG_SND_SOC_RK3506=y +CONFIG_SND_SOC_RK730=y CONFIG_SND_SOC_RK_DSM=y CONFIG_SND_SIMPLE_CARD=y # CONFIG_USB_HID is not set diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 89dc2b101ba6..5a931f086c33 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1939,6 +1939,20 @@ static int vop_plane_atomic_check(struct drm_plane *plane, new_plane_state->rotation); return -EINVAL; } + + /* RK3399 AFBC act_h must aligned as 16 line */ + if (vop->version == VOP_VERSION_RK3399_BIG) { + u32 old_act_h = drm_rect_height(src) >> 16; + + if (!IS_ALIGNED(old_act_h, 16)) { + u32 aligned_act_h = ALIGN_DOWN(old_act_h, 16); + + src->y2 = ((src->y1 >> 16) + aligned_act_h) << 16; + + DRM_DEBUG_KMS("Win%d afbc act_h:%d isn't aligned as 16, so change to: %d\n", + win->win_id, old_act_h, aligned_act_h); + } + } } offset = (src->x1 >> 16) * fb->format->cpp[0]; @@ -3871,6 +3885,13 @@ static int vop_afbdc_atomic_check(struct drm_crtc *crtc, if (fb->modifier & AFBC_FORMAT_MOD_YTR) s->afbdc_win_format |= AFBC_Y2R_COLOR_TRANSFORM; s->afbdc_win_width = fb->width - 1; + /* RK3399 AFBC can't supported vir width */ + if (vop->version == VOP_VERSION_RK3399_BIG && + fb->width != drm_rect_width(src) >> 16) { + DRM_ERROR("Win%d afbc unsupported vir width: fb->width: %d, act_w: %d\n", + win->win_id, fb->width, drm_rect_width(src) >> 16); + return -EINVAL; + } s->afbdc_win_height = (drm_rect_height(src) >> 16) - 1; s->afbdc_win_id = win->win_id; s->afbdc_win_ptr = plane_state->yrgb_mst; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index e17c8c4a55f6..9577d9930db8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -342,11 +342,6 @@ static const uint64_t format_modifiers_afbc_tiled_for_vop3[] = { AFBC_FORMAT_MOD_CBR | AFBC_FORMAT_MOD_SPLIT), - DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | - AFBC_FORMAT_MOD_YTR | - AFBC_FORMAT_MOD_SPARSE | - AFBC_FORMAT_MOD_SPLIT), - DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 | AFBC_FORMAT_MOD_CBR | AFBC_FORMAT_MOD_SPARSE | diff --git a/drivers/media/platform/rockchip/isp/dev.c b/drivers/media/platform/rockchip/isp/dev.c index 301a0341bae8..49999b58ea87 100644 --- a/drivers/media/platform/rockchip/isp/dev.c +++ b/drivers/media/platform/rockchip/isp/dev.c @@ -470,7 +470,7 @@ static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init) struct v4l2_subdev *isp; struct v4l2_subdev_format fmt; struct v4l2_subdev_selection sel; - u32 i, width, height, code; + u32 width, height, code; memset(&sel, 0, sizeof(sel)); memset(&fmt, 0, sizeof(fmt)); @@ -551,14 +551,6 @@ static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init) } if (dev->isp_ver == ISP_V30) { - struct v4l2_pix_format_mplane pixm = { - .width = width, - .height = height, - .pixelformat = rkisp_mbus_pixelcode_to_v4l2(code), - }; - - for (i = RKISP_STREAM_RAWRD0; i <= RKISP_STREAM_RAWRD2; i++) - rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[i], pixm); rkisp_set_stream_def_fmt(dev, RKISP_STREAM_FBC, width, height, V4L2_PIX_FMT_FBC0); #ifdef RKISP_STREAM_BP_EN @@ -567,25 +559,13 @@ static int _set_pipeline_default_fmt(struct rkisp_device *dev, bool is_init) #endif } - if (dev->isp_ver == ISP_V32 || - dev->isp_ver == ISP_V32_L || - dev->isp_ver == ISP_V39) { - struct v4l2_pix_format_mplane pixm = { - .width = width, - .height = height, - .pixelformat = rkisp_mbus_pixelcode_to_v4l2(code), - }; - - rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0], pixm); - rkisp_dmarx_set_fmt(&dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2], pixm); - if (dev->isp_ver == ISP_V32) { - rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP, - width, height, V4L2_PIX_FMT_NV12); - rkisp_set_stream_def_fmt(dev, RKISP_STREAM_MPDS, - width / 4, height / 4, V4L2_PIX_FMT_NV12); - rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BPDS, - width / 4, height / 4, V4L2_PIX_FMT_NV12); - } + if (dev->isp_ver == ISP_V32) { + rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BP, + width, height, V4L2_PIX_FMT_NV12); + rkisp_set_stream_def_fmt(dev, RKISP_STREAM_MPDS, + width / 4, height / 4, V4L2_PIX_FMT_NV12); + rkisp_set_stream_def_fmt(dev, RKISP_STREAM_BPDS, + width / 4, height / 4, V4L2_PIX_FMT_NV12); } if (dev->isp_ver == ISP_V39) rkisp_set_stream_def_fmt(dev, RKISP_STREAM_LDC, width, height, V4L2_PIX_FMT_NV12); diff --git a/drivers/media/platform/rockchip/isp/dmarx.c b/drivers/media/platform/rockchip/isp/dmarx.c index 77be7e0b439c..22691b78f289 100644 --- a/drivers/media/platform/rockchip/isp/dmarx.c +++ b/drivers/media/platform/rockchip/isp/dmarx.c @@ -843,10 +843,23 @@ static int rkisp_set_fmt(struct rkisp_stream *stream, if (stream->ispdev->vicap_in.merge_num > 1) bytesperline *= stream->ispdev->vicap_in.merge_num; - - if (i != 0 || - plane_fmt->bytesperline < bytesperline) - plane_fmt->bytesperline = bytesperline; + /* bytesperline from user */ + if (plane_fmt->bytesperline) { + bytesperline = width * fmt->bpp[i] / 8; + if (plane_fmt->bytesperline < bytesperline) { + bytesperline = ALIGN(bytesperline, 4); + v4l2_err(&stream->ispdev->v4l2_dev, + "rawrd bytesperline:%d error, force to %d\n", + plane_fmt->bytesperline, bytesperline); + } else { + bytesperline = ALIGN(plane_fmt->bytesperline, 4); + if (bytesperline != plane_fmt->bytesperline) + v4l2_err(&stream->ispdev->v4l2_dev, + "rawrd bytesperline need 4 align, force to %d\n", + bytesperline); + } + } + plane_fmt->bytesperline = bytesperline; plane_fmt->sizeimage = plane_fmt->bytesperline * height; diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index e41c69749e86..5a343bcbc5cb 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -2621,6 +2621,7 @@ static int rkisp_isp_sd_set_fmt(struct v4l2_subdev *sd, } if (fmt->pad == RKISP_ISP_PAD_SINK) { + struct v4l2_pix_format_mplane pixm = { 0 }; const struct ispsd_in_fmt *in_fmt; in_fmt = find_in_fmt(mf->code); @@ -2631,6 +2632,14 @@ static int rkisp_isp_sd_set_fmt(struct v4l2_subdev *sd, isp_sd->in_fmt = *in_fmt; isp_sd->in_frm = *mf; + /* rawrd video format with isp input format change */ + pixm.width = mf->width; + pixm.height = mf->height; + pixm.pixelformat = rkisp_mbus_pixelcode_to_v4l2(mf->code); + rkisp_dmarx_set_fmt(&isp_dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0], pixm); + rkisp_dmarx_set_fmt(&isp_dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2], pixm); + if (isp_dev->isp_ver == ISP_V20 || isp_dev->isp_ver == ISP_V30) + rkisp_dmarx_set_fmt(&isp_dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1], pixm); } else if (fmt->pad == RKISP_ISP_PAD_SOURCE_PATH) { const struct ispsd_out_fmt *out_fmt; diff --git a/drivers/memory/rockchip/dsmc-controller.c b/drivers/memory/rockchip/dsmc-controller.c index 41565b7254c6..de8770bc800f 100644 --- a/drivers/memory/rockchip/dsmc-controller.c +++ b/drivers/memory/rockchip/dsmc-controller.c @@ -87,7 +87,8 @@ static int find_attr_region(struct dsmc_config_cs *cfg, uint32_t attribute) int region; for (region = 0; region < DSMC_LB_MAX_RGN; region++) { - if (cfg->slv_rgn[region].attribute == attribute) + if ((cfg->slv_rgn[region].status) && + (cfg->slv_rgn[region].attribute == attribute)) return region; } return -1; @@ -264,7 +265,8 @@ static int dsmc_ctrller_cfg_for_lb(struct rockchip_dsmc *dsmc, uint32_t cs) struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs]; writel(dsmc->cfg.clk_mode, dsmc->regs + DSMC_CLK_MD); - writel(MTR_CFG(3, 3, 1, 1, 0, 0, + writel(MTR_CFG(cfg->rcshi, cfg->wcshi, cfg->rcss, cfg->wcss, + cfg->rcsh, cfg->wcsh, calc_ltcy_value(cfg->rd_latency), calc_ltcy_value(cfg->wr_latency)), dsmc->regs + DSMC_MTR(cs)); @@ -287,13 +289,18 @@ static int dsmc_ctrller_cfg_for_lb(struct rockchip_dsmc *dsmc, uint32_t cs) (slv_rgn->cs0_ctrl << RGNX_ATTR_CTRL_SHIFT) | (slv_rgn->cs0_be_ctrled << RGNX_ATTR_BE_CTRLED_SHIFT) | value | - (slv_rgn->ca_addr_width << + (RGNX_ATTR_32BIT_ADDR_WIDTH << RGNX_ATTR_ADDR_WIDTH_SHIFT), dsmc->regs + DSMC_RGN0_ATTR(cs) + 4 * i); } /* clear and enable interrupt */ - writel(INT_STATUS(cs), dsmc->regs + DSMC_INT_STATUS); - writel(INT_EN(cs), dsmc->regs + DSMC_INT_EN); + writel(INT_STATUS(cfg->int_en), dsmc->regs + DSMC_INT_STATUS); + writel(INT_EN(cfg->int_en), dsmc->regs + DSMC_INT_EN); + + if (dsmc->cfg.dma_req_mux_offset && (cs < 2)) + REG_CLRSETBITS(dsmc, dsmc->cfg.dma_req_mux_offset, + DMA_REQ_MUX_MASK(cs), + DMA_REQ_MUX(cs, dsmc->cfg.cs_cfg[cs].int_en)); return 0; } @@ -347,6 +354,12 @@ static int dsmc_slv_cmn_config(struct rockchip_dsmc *dsmc, struct dsmc_map *region_map = &dsmc->cs_map[cs].region_map[0]; struct dsmc_config_cs *cfg = &dsmc->cfg.cs_cfg[cs]; + tmp = lb_read_cmn(region_map, CMN_CON(3)); + tmp |= 0x1 << RDYN_GEN_CTRL_SHIFT; + tmp &= ~(DATA_WIDTH_MASK << DATA_WIDTH_SHIFT); + tmp |= cfg->io_width << DATA_WIDTH_SHIFT; + lb_write_cmn(region_map, CMN_CON(3), tmp); + tmp = lb_read_cmn(region_map, CMN_CON(0)); if (slv_rgn->dummy_clk_num == 0) { tmp &= ~(WR_DATA_CYC_EXTENDED_MASK << WR_DATA_CYC_EXTENDED_SHIFT); @@ -356,13 +369,6 @@ static int dsmc_slv_cmn_config(struct rockchip_dsmc *dsmc, pr_err("DSMC: lb slave: dummy clk too large\n"); return -1; } - tmp &= ~(RD_LATENCY_CYC_MASK << RD_LATENCY_CYC_SHIFT); - if ((cfg->rd_latency == 1) || (cfg->rd_latency == 2)) { - tmp |= cfg->rd_latency << RD_LATENCY_CYC_SHIFT; - } else { - pr_err("DSMC: lb slave: read latency value error\n"); - return -1; - } tmp &= ~(CA_CYC_MASK << CA_CYC_SHIFT); if (slv_rgn->ca_addr_width == RGNX_ATTR_32BIT_ADDR_WIDTH) @@ -372,12 +378,6 @@ static int dsmc_slv_cmn_config(struct rockchip_dsmc *dsmc, lb_write_cmn(region_map, CMN_CON(0), tmp); - tmp = lb_read_cmn(region_map, CMN_CON(3)); - tmp |= 0x1 << RDYN_GEN_CTRL_SHIFT; - tmp &= ~(DATA_WIDTH_MASK << DATA_WIDTH_SHIFT); - tmp |= cfg->io_width << DATA_WIDTH_SHIFT; - lb_write_cmn(region_map, CMN_CON(3), tmp); - return 0; } @@ -396,9 +396,6 @@ static int dsmc_lb_cmn_config(struct rockchip_dsmc *dsmc, uint32_t cs) (MCR_IOWIDTH_X8 << MCR_IOWIDTH_SHIFT) | (MCR_CRT_CR_SPACE << MCR_CRT_SHIFT)); - slv_rgn = &cfg->slv_rgn[0]; - ret = dsmc_slv_cmn_config(dsmc, slv_rgn, cs); - for (i = 0; i < DSMC_LB_MAX_RGN; i++) { slv_rgn = &cfg->slv_rgn[i]; if (!slv_rgn->status) @@ -408,9 +405,22 @@ static int dsmc_lb_cmn_config(struct rockchip_dsmc *dsmc, uint32_t cs) break; } + slv_rgn = &cfg->slv_rgn[0]; + ret = dsmc_slv_cmn_config(dsmc, slv_rgn, cs); + /* config to memory space */ writel(tmp, dsmc->regs + DSMC_MCR(cs)); + for (i = 0; i < DSMC_LB_MAX_RGN; i++) { + slv_rgn = &cfg->slv_rgn[i]; + if (!slv_rgn->status) + continue; + + REG_CLRSETBITS(dsmc, DSMC_RGN0_ATTR(cs) + 4 * i, + RGNX_ATTR_CA_ADDR_MASK << RGNX_ATTR_ADDR_WIDTH_SHIFT, + slv_rgn->ca_addr_width << RGNX_ATTR_ADDR_WIDTH_SHIFT); + } + return ret; } @@ -470,7 +480,7 @@ static int dsmc_psram_cfg(struct rockchip_dsmc *dsmc, uint32_t cs) (MCR_CRT_CR_SPACE << MCR_CRT_SHIFT)); if (cs_cfg->protcl == OPI_XCCELA_PSRAM) { /* Xccela psram init */ - uint8_t mr_tmp; + uint8_t mr_tmp, rbxen; mr_tmp = xccela_read_mr(region_map, 0); tmp = cs_cfg->rd_latency - 3; @@ -497,6 +507,14 @@ static int dsmc_psram_cfg(struct rockchip_dsmc *dsmc, uint32_t cs) dsmc_cfg_latency(cs_cfg->rd_latency, cs_cfg->wr_latency, dsmc, cs); + mr_tmp = xccela_read_mr(region_map, 3); + if ((mr_tmp >> XCCELA_MR3_RBXEN_SHIFT) & XCCELA_MR3_RBXEN_MASK) { + rbxen = 1; + cs_cfg->rd_bdr_xfer_en = 0; + } else { + rbxen = 0; + } + mr_tmp = xccela_read_mr(region_map, 8); if (cs_cfg->io_width == MCR_IOWIDTH_X16) { @@ -513,11 +531,23 @@ static int dsmc_psram_cfg(struct rockchip_dsmc *dsmc, uint32_t cs) else if (cs_cfg->wrap_size == MCR_WRAPSIZE_32_CLK) mr_tmp |= (XCCELA_MR8_BL_32_CLK << XCCELA_MR8_BL_SHIFT); + mr_tmp |= rbxen << XCCELA_MR8_RBX_EN_SHIFT; + xccela_write_mr(region_map, 8, mr_tmp); } else { /* Hyper psram init */ uint16_t cr_tmp; + cr_tmp = hyper_read_mr(region_map, HYPER_PSRAM_IR0); + if (((cr_tmp >> IR0_ROW_COUNT_SHIFT) & IR0_ROW_COUNT_MASK) == + IR0_ROW_COUNT_128MBIT) { + cs_cfg->rd_bdr_xfer_en = 1; + cs_cfg->wr_bdr_xfer_en = 1; + } else { + cs_cfg->rd_bdr_xfer_en = 0; + cs_cfg->wr_bdr_xfer_en = 0; + } + cr_tmp = hyper_read_mr(region_map, HYPER_PSRAM_CR0); latency = cs_cfg->wr_latency; @@ -652,8 +682,8 @@ static void dsmc_psram_remodify_timing(struct rockchip_dsmc *dsmc, uint32_t cs) (BDRTCR_WR_BDR_XFER_EN_MASK << BDRTCR_WR_BDR_XFER_EN_SHIFT) | (BDRTCR_RD_BDR_XFER_EN_MASK << BDRTCR_RD_BDR_XFER_EN_SHIFT), ((tmp - 6) << BDRTCR_COL_BIT_NUM_SHIFT) | - (BDRTCR_WR_BDR_XFER_EN << BDRTCR_WR_BDR_XFER_EN_SHIFT) | - (BDRTCR_RD_BDR_XFER_EN << BDRTCR_RD_BDR_XFER_EN_SHIFT)); + (cs_cfg->wr_bdr_xfer_en << BDRTCR_WR_BDR_XFER_EN_SHIFT) | + (cs_cfg->rd_bdr_xfer_en << BDRTCR_RD_BDR_XFER_EN_SHIFT)); } static void dsmc_lb_dma_clear_s2h_intrupt(struct rockchip_dsmc *dsmc, uint32_t cs) diff --git a/drivers/memory/rockchip/dsmc-host.c b/drivers/memory/rockchip/dsmc-host.c index 42534174b442..0aec9eb8ca64 100644 --- a/drivers/memory/rockchip/dsmc-host.c +++ b/drivers/memory/rockchip/dsmc-host.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -31,10 +32,12 @@ static __maybe_unused int rk3576_dsmc_platform_init(struct platform_device *pdev) { uint32_t i, val; - const struct rockchip_dsmc_device *priv; + struct rockchip_dsmc_device *priv; priv = platform_get_drvdata(pdev); + priv->dsmc.cfg.dma_req_mux_offset = 0x0; + if (IS_ERR_OR_NULL(priv->dsmc.grf)) { dev_err(priv->dsmc.dev, "Missing rockchip,grf property\n"); return -ENODEV; @@ -55,11 +58,65 @@ static __maybe_unused int rk3576_dsmc_platform_init(struct platform_device *pdev return 0; } +static __maybe_unused int rk3506_dsmc_platform_init(struct platform_device *pdev) +{ + int ret = 0; + uint32_t i; + struct device *dev = &pdev->dev; + struct pinctrl *pinctrl; + struct pinctrl_state *pinctrl_active; + struct pinctrl_state *pinctrl_lb_slave; + const struct rockchip_dsmc_device *priv; + + priv = platform_get_drvdata(pdev); + + pinctrl = devm_pinctrl_get(dev); + if (IS_ERR(pinctrl)) { + dev_err(dev, "Failed to get pinctrl\n"); + return PTR_ERR(pinctrl); + } + + pinctrl_active = pinctrl_lookup_state(pinctrl, "active"); + if (IS_ERR(pinctrl_active)) { + dev_err(dev, "Failed to lookup active pinctrl state\n"); + return PTR_ERR(pinctrl_active); + } + + ret = pinctrl_select_state(pinctrl, pinctrl_active); + if (ret) { + dev_err(dev, "Failed to select active pinctrl state\n"); + return ret; + } + + pinctrl_lb_slave = pinctrl_lookup_state(pinctrl, "lb-slave"); + if (IS_ERR(pinctrl_lb_slave)) { + dev_err(dev, "Failed to lookup lb-slave pinctrl state\n"); + return PTR_ERR(pinctrl_lb_slave); + } + + for (i = 0; i < DSMC_MAX_SLAVE_NUM; i++) { + if (priv->dsmc.cfg.cs_cfg[i].device_type == DSMC_LB_DEVICE) { + ret = pinctrl_select_state(pinctrl, pinctrl_lb_slave); + if (ret) { + dev_err(dev, "Failed to select lb-slave pinctrl state\n"); + return ret; + } + break; + } + } + + return ret; +} + static const struct of_device_id dsmc_of_match[] = { #if IS_ENABLED(CONFIG_CPU_RK3576) { .compatible = "rockchip,rk3576-dsmc", .data = rk3576_dsmc_platform_init }, +#elif IS_ENABLED(CONFIG_CPU_RK3506) + { + .compatible = "rockchip,rk3506-dsmc", .data = rk3506_dsmc_platform_init + }, #endif {}, }; @@ -84,7 +141,6 @@ static int rockchip_dsmc_platform_init(struct platform_device *pdev) return 0; } -#ifdef CONFIG_ARM64 static void *rk_dsmc_map_kernel(phys_addr_t start, size_t len, uint32_t mem_attr) { void *vaddr; @@ -104,44 +160,6 @@ static void rk_dsmc_unmap_kernel(void *vaddr) if (vaddr != NULL) iounmap(vaddr); } -#else -static void *rk_dsmc_map_kernel(phys_addr_t start, size_t len, uint32_t mem_attr) -{ - int i; - void *vaddr; - pgprot_t pgprot; - phys_addr_t phys; - int npages = PAGE_ALIGN(len) / PAGE_SIZE; - struct page **p = vmalloc(sizeof(struct page *) * npages); - - if (!p) - return NULL; - - if (mem_attr == DSMC_MEM_ATTRIBUTE_CACHE) - pgprot = PAGE_KERNEL; - else if (mem_attr == DSMC_MEM_ATTRIBUTE_WR_COM) - pgprot = pgprot_writecombine(PAGE_KERNEL); - else - pgprot = pgprot_noncached(PAGE_KERNEL); - - phys = start; - for (i = 0; i < npages; i++) { - p[i] = phys_to_page(phys); - phys += PAGE_SIZE; - } - - vaddr = vmap(p, npages, VM_MAP, pgprot); - vfree(p); - - return vaddr; -} - -static void rk_dsmc_unmap_kernel(void *vaddr) -{ - if (vaddr != NULL) - vunmap(vaddr); -} -#endif static int dsmc_parse_dt_regions(struct platform_device *pdev, struct device_node *lb_np, struct dsmc_config_cs *cfg) @@ -223,8 +241,6 @@ static int dsmc_parse_dt_regions(struct platform_device *pdev, struct device_nod if (rgn->status) cfg->rgn_num++; of_node_put(child_node); - } else { - dev_warn(dev, "Failed to find node: %s\n", region_name); } } @@ -239,24 +255,48 @@ static int dsmc_reg_remap(struct device *dev, struct dsmc_ctrl_config *cfg, uint32_t *dqs_dll) { int ret = 0; - uint32_t cs, rgn_num_max; + uint32_t cs, rgn, rgn_num_max; + uint32_t num = 0; struct dsmc_map *region_map; rgn_num_max = 1; for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { if (cfg->cs_cfg[cs].device_type == DSMC_UNKNOWN_DEVICE) continue; - region_map = &dsmc->cs_map[cs].region_map[0]; - cfg->cap = max_t(uint32_t, cfg->cap, region_map->size); + if (cfg->cs_cfg[cs].rgn_num == 3) + cfg->cs_cfg[cs].rgn_num++; rgn_num_max = max_t(uint32_t, rgn_num_max, cfg->cs_cfg[cs].rgn_num); + } - region_map->virt = rk_dsmc_map_kernel(region_map->phys, - region_map->size, - DSMC_MEM_ATTRIBUTE_NO_CACHE); - if (!region_map->virt) { - dev_err(dev, "Failed to remap slave cs%d memory\n", cs); - ret = -EINVAL; - continue; + for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { + if (cfg->cs_cfg[cs].device_type == OPI_XCCELA_PSRAM) { + region_map = &dsmc->cs_map[cs].region_map[0]; + region_map->phys = (phys_addr_t)(mem_ranges[0] + cs * mem_ranges[1]); + region_map->size = (size_t)mem_ranges[1]; + cfg->cap = max_t(uint32_t, cfg->cap, region_map->size); + region_map->virt = rk_dsmc_map_kernel(region_map->phys, + region_map->size, + DSMC_MEM_ATTRIBUTE_NO_CACHE); + } else if (cfg->cs_cfg[cs].device_type == DSMC_LB_DEVICE) { + for (rgn = 0; rgn < DSMC_LB_MAX_RGN; rgn++) { + if (!cfg->cs_cfg[cs].slv_rgn[rgn].status) + continue; + region_map = &dsmc->cs_map[cs].region_map[rgn]; + region_map->phys = (phys_addr_t)(mem_ranges[0] + + rgn_num_max * mem_ranges[1] * cs + + num * mem_ranges[1]); + region_map->size = (size_t)mem_ranges[1]; + cfg->cap = max_t(uint32_t, cfg->cap, region_map->size); + num++; + region_map->virt = rk_dsmc_map_kernel(region_map->phys, + region_map->size, + DSMC_MEM_ATTRIBUTE_NO_CACHE); + if (!region_map->virt) { + dev_err(dev, "Failed to remap slave cs%d memory\n", + cs); + ret = -EINVAL; + } + } } } cfg->cap *= rgn_num_max; @@ -264,23 +304,6 @@ static int dsmc_reg_remap(struct device *dev, struct dsmc_ctrl_config *cfg, return ret; } -static void dsmc_lb_memory_get(struct dsmc_config_cs *cfg, struct dsmc_cs_map *cs_map) -{ - int rgn; - phys_addr_t cphys = cs_map->region_map[0].phys; - - if (cfg->rgn_num == 3) - cfg->rgn_num++; - - for (rgn = 1; rgn < DSMC_LB_MAX_RGN; rgn++) { - if (cfg->slv_rgn[rgn].status) { - cphys += cs_map->region_map[0].size; - cs_map->region_map[rgn].phys = cphys; - cs_map->region_map[rgn].size = cs_map->region_map[0].size; - } - } -} - static int dsmc_mem_remap(struct device *dev, struct rockchip_dsmc *dsmc) { int ret = 0; @@ -334,7 +357,6 @@ static int dsmc_mem_remap(struct device *dev, struct rockchip_dsmc *dsmc) if (!region_map->virt) { dev_err(dev, "Failed to remap psram cs%d memory\n", cs); ret = -EINVAL; - continue; } } } @@ -349,12 +371,13 @@ static int dsmc_parse_dt(struct platform_device *pdev, struct rockchip_dsmc *dsm uint32_t psram = 0, lb_slave = 0; uint64_t mem_ranges[2]; uint32_t dqs_dll[2 * DSMC_MAX_SLAVE_NUM]; + uint32_t mtr_timing[8]; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device_node *child_node; - struct device_node *slave_np, *dsmc_slave_np, *psram_np, *lb_slave_np; + struct device_node *slave_np, *dsmc_slave_np; + struct device_node *psram_np = NULL, *lb_slave_np = NULL; struct dsmc_ctrl_config *cfg = &dsmc->cfg; - struct dsmc_map *region_map; char slave_name[16]; slave_np = of_get_child_by_name(np, "slave"); @@ -371,6 +394,11 @@ static int dsmc_parse_dt(struct platform_device *pdev, struct rockchip_dsmc *dsm goto release_slave_node; } + for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { + cfg->cs_cfg[cs].dll_num[0] = dqs_dll[2 * cs]; + cfg->cs_cfg[cs].dll_num[1] = dqs_dll[2 * cs + 1]; + } + ret = of_property_read_u64_array(slave_np, "rockchip,ranges", mem_ranges, ARRAY_SIZE(mem_ranges)); if (ret) { @@ -391,54 +419,64 @@ static int dsmc_parse_dt(struct platform_device *pdev, struct rockchip_dsmc *dsm } psram_np = of_get_child_by_name(dsmc_slave_np, "psram"); - if (!psram_np) { - dev_err(dev, "Failed to get psram node\n"); - ret = -ENODEV; - goto release_dsmc_slave_node; - } - for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { - region_map = &dsmc->cs_map[cs].region_map[0]; - region_map->phys = mem_ranges[0] + cs * mem_ranges[1]; - region_map->size = mem_ranges[1]; - cfg->cs_cfg[cs].dll_num[0] = dqs_dll[2 * cs]; - cfg->cs_cfg[cs].dll_num[1] = dqs_dll[2 * cs + 1]; - - snprintf(slave_name, sizeof(slave_name), "psram%d", cs); - child_node = of_get_child_by_name(psram_np, slave_name); - if (child_node) { - if (of_device_is_available(child_node)) { - cfg->cs_cfg[cs].device_type = OPI_XCCELA_PSRAM; - psram = 1; + if (psram_np) { + for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { + snprintf(slave_name, sizeof(slave_name), "psram%d", cs); + child_node = of_get_child_by_name(psram_np, slave_name); + if (!child_node) + continue; + if (!of_device_is_available(child_node)) { of_node_put(child_node); continue; } + cfg->cs_cfg[cs].device_type = OPI_XCCELA_PSRAM; + psram = 1; of_node_put(child_node); } } - if (psram) - goto release_psram_node; - lb_slave_np = of_get_child_by_name(dsmc_slave_np, "lb-slave"); - if (!lb_slave_np) { - dev_err(dev, "Failed to get lb_slave node\n"); - ret = -ENODEV; - goto release_psram_node; - } - for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { - snprintf(slave_name, sizeof(slave_name), "lb-slave%d", cs); - child_node = of_get_child_by_name(lb_slave_np, slave_name); - if (child_node) { - if (of_device_is_available(child_node)) { - cfg->cs_cfg[cs].device_type = DSMC_LB_DEVICE; - lb_slave = 1; - if (dsmc_parse_dt_regions(pdev, child_node, - &cfg->cs_cfg[cs])) { - ret = -ENODEV; - of_node_put(child_node); - goto release_lb_node; - } - dsmc_lb_memory_get(&cfg->cs_cfg[cs], &dsmc->cs_map[cs]); + if (lb_slave_np) { + for (cs = 0; cs < DSMC_MAX_SLAVE_NUM; cs++) { + snprintf(slave_name, sizeof(slave_name), "lb-slave%d", cs); + child_node = of_get_child_by_name(lb_slave_np, slave_name); + if (!child_node) + continue; + if (!of_device_is_available(child_node)) { + of_node_put(child_node); + continue; + } + cfg->cs_cfg[cs].device_type = DSMC_LB_DEVICE; + lb_slave = 1; + ret = of_property_read_u32_array(child_node, + "rockchip,mtr-timing", + mtr_timing, 8); + if (ret) { + dev_err(dev, "Fail to get rockchip,mtr-timing\n"); + of_node_put(child_node); + goto release_dsmc_slave_node; + } + cfg->cs_cfg[cs].rcshi = mtr_timing[0]; + cfg->cs_cfg[cs].wcshi = mtr_timing[1]; + cfg->cs_cfg[cs].rcss = mtr_timing[2]; + cfg->cs_cfg[cs].wcss = mtr_timing[3]; + cfg->cs_cfg[cs].rcsh = mtr_timing[4]; + cfg->cs_cfg[cs].wcsh = mtr_timing[5]; + cfg->cs_cfg[cs].rd_latency = mtr_timing[6]; + cfg->cs_cfg[cs].wr_latency = mtr_timing[7]; + + ret = of_property_read_u32(child_node, + "rockchip,int-en", + &cfg->cs_cfg[cs].int_en); + if (ret) { + dev_warn(dev, "used default rockchip,int-en\n"); + cfg->cs_cfg[cs].int_en = cs; + } + if (dsmc_parse_dt_regions(pdev, child_node, + &cfg->cs_cfg[cs])) { + ret = -ENODEV; + of_node_put(child_node); + goto release_dsmc_slave_node; } of_node_put(child_node); } @@ -447,20 +485,17 @@ static int dsmc_parse_dt(struct platform_device *pdev, struct rockchip_dsmc *dsm if (psram && lb_slave) { dev_err(dev, "Can't have both psram and lb_slave\n"); ret = -ENODEV; - goto release_lb_node; + goto release_dsmc_slave_node; } else if (!(psram || lb_slave)) { dev_err(dev, "psram or lb_slave need open in dts\n"); ret = -ENODEV; - goto release_lb_node; + goto release_dsmc_slave_node; } - ret = dsmc_reg_remap(dev, cfg, dsmc, mem_ranges, dqs_dll); -release_lb_node: - of_node_put(lb_slave_np); -release_psram_node: - of_node_put(psram_np); release_dsmc_slave_node: + of_node_put(psram_np); + of_node_put(lb_slave_np); of_node_put(dsmc_slave_np); release_slave_node: of_node_put(slave_np); @@ -554,7 +589,6 @@ static int rockchip_dsmc_lb_prepare_tx_dma(struct device *dev, }; dmaengine_slave_config(dsmc->dma_req[cs], &txconf); - txdesc = dmaengine_prep_slave_single( dsmc->dma_req[cs], xfer->src_addr, @@ -708,13 +742,13 @@ static void dsmc_data_init(struct rockchip_dsmc *dsmc) cs_cfg->acs = 1; cs_cfg->max_length_en = 1; cs_cfg->max_length = 0xff; + cs_cfg->rd_bdr_xfer_en = 1; + cs_cfg->wr_bdr_xfer_en = 1; } else { cs_cfg->io_width = MCR_IOWIDTH_X16; cs_cfg->wrap_size = DSMC_BURST_WRAPSIZE_16CLK; - cs_cfg->rd_latency = 2; - cs_cfg->wr_latency = 2; cs_cfg->wrap2incr_en = 1; - cs_cfg->acs = 0; + cs_cfg->acs = 1; cs_cfg->max_length_en = 0; cs_cfg->max_length = 0x0; } @@ -865,10 +899,6 @@ static int rk_dsmc_probe(struct platform_device *pdev) return ret; } - ret = rockchip_dsmc_platform_init(pdev); - if (ret) - return ret; - ret = device_property_read_u32(dev, "clock-frequency", &dsmc->cfg.freq_hz); if (ret) { dev_err(dev, "Failed to read clock-frequency property!\n"); @@ -876,12 +906,16 @@ static int rk_dsmc_probe(struct platform_device *pdev) } dsmc->cfg.ctrl_freq_hz = dsmc->cfg.freq_hz * 2; + dsmc->cfg.dma_req_mux_offset = DSMC_DMA_MUX; if (dsmc_parse_dt(pdev, dsmc)) { ret = -ENODEV; dev_err(dev, "The dts parameters get fail! ret = %d\n", ret); return ret; } + ret = rockchip_dsmc_platform_init(pdev); + if (ret) + return ret; dsmc->areset = devm_reset_control_get(dev, "dsmc"); if (IS_ERR(dsmc->areset)) { diff --git a/drivers/memory/rockchip/dsmc-host.h b/drivers/memory/rockchip/dsmc-host.h index 501399bdd328..fc28a3932905 100644 --- a/drivers/memory/rockchip/dsmc-host.h +++ b/drivers/memory/rockchip/dsmc-host.h @@ -74,6 +74,10 @@ #define DMA_REQ_EN(cs) (0x1 << (cs)) #define DMA_REQ_DIS(cs) (0x0 << (cs)) +/* DSMC_DMA_MUX */ +#define DMA_REQ_MUX_MASK(req) (0x3 << ((req) * 4)) +#define DMA_REQ_MUX(req, n) (((n) & 0x3) << ((req) * 4)) + /* VDMC */ #define VDMC_MID_SHIFT 0 #define VDMC_MID_MASK 0xF @@ -166,6 +170,7 @@ #define RGNX_ATTR_BE_CTRLED_SHIFT 5 #define RGNX_ATTR_DUM_CLK_EN_SHIFT 6 #define RGNX_ATTR_DUM_CLK_NUM_SHIFT 7 +#define RGNX_ATTR_CA_ADDR_MASK 1 #define RGNX_ATTR_32BIT_ADDR_WIDTH 0 #define RGNX_ATTR_16BIT_ADDR_WIDTH 1 #define RGNX_ATTR_ADDR_WIDTH_SHIFT 8 @@ -201,6 +206,7 @@ #define XCCELA_PSRAM_MR_SET(n) (((n) & 0xff) << 8) /* device id bit mask */ #define HYPERBUS_DEV_ID_MASK (0xf) +#define IR0_ROW_COUNT_128MBIT (0xd) #define IR0_ROW_COUNT_SHIFT (0x8) #define IR0_ROW_COUNT_MASK (0x1f) #define IR0_COL_COUNT_SHIFT (0x4) @@ -239,6 +245,9 @@ #define XCCELA_MR2_DEV_DENSITY_MASK (0x7) +#define XCCELA_MR3_RBXEN_MASK (1) +#define XCCELA_MR3_RBXEN_SHIFT (7) + #define XCCELA_MR4_WL_SHIFT (5) #define XCCELA_MR4_WL_MASK (0x7) @@ -246,6 +255,9 @@ #define XCCELA_MR8_IO_TYPE_MASK (0x1) #define XCCELA_MR8_IO_TYPE_X16 (0x1) #define XCCELA_MR8_IO_TYPE_X8 (0x0) +#define XCCELA_MR8_RBX_EN_SHIFT (3) +#define XCCELA_MR8_RBX_EN_MASK (0x1) +#define XCCELA_MR8_RBX_EN (0x1) #define XCCELA_MR8_BL_SHIFT (0) #define XCCELA_MR8_BL_MASK (0x7) #define XCCELA_MR8_BL_32_CLK (0x2) @@ -284,6 +296,16 @@ #define RK3576_IOMUX_SEL(v, s) (((v) << (s)) | (0xf << ((s) + 16))) +#define RK3506_GPIO1A_IOMUX_SEL_0_OFFSET (0x20) +#define RK3506_GPIO1A_IOMUX_SEL_1_OFFSET (0x24) +#define RK3506_GPIO1B_IOMUX_SEL_0_OFFSET (0x28) +#define RK3506_GPIO1B_IOMUX_SEL_1_OFFSET (0x2c) +#define RK3506_GPIO1C_IOMUX_SEL_0_OFFSET (0x30) +#define RK3506_GPIO1C_IOMUX_SEL_1_OFFSET (0x34) +#define RK3506_GPIO1D_IOMUX_SEL_0_OFFSET (0x38) + +#define RK3506_IOMUX_SEL(v, s) (((v) << (s)) | (0xf << ((s) + 16))) + struct regions_config { uint32_t attribute; uint32_t ca_addr_width; @@ -303,6 +325,12 @@ struct dsmc_config_cs { uint32_t exclusive_dqs; uint32_t io_width; uint32_t wrap_size; + uint32_t rcshi; + uint32_t wcshi; + uint32_t rcss; + uint32_t wcss; + uint32_t rcsh; + uint32_t wcsh; uint32_t rd_latency; uint32_t wr_latency; uint32_t col; @@ -311,6 +339,9 @@ struct dsmc_config_cs { uint32_t max_length; uint32_t rgn_num; uint32_t dll_num[2]; + uint32_t rd_bdr_xfer_en; + uint32_t wr_bdr_xfer_en; + uint32_t int_en; struct regions_config slv_rgn[DSMC_LB_MAX_RGN]; }; @@ -319,6 +350,7 @@ struct dsmc_ctrl_config { uint32_t freq_hz; uint32_t ctrl_freq_hz; uint32_t cap; + uint32_t dma_req_mux_offset; struct dsmc_config_cs cs_cfg[DSMC_MAX_SLAVE_NUM]; }; diff --git a/sound/soc/codecs/rk730.c b/sound/soc/codecs/rk730.c index 3c24ec136716..d36ab6fd7b57 100644 --- a/sound/soc/codecs/rk730.c +++ b/sound/soc/codecs/rk730.c @@ -19,9 +19,24 @@ #include #include #include - #include "rk730.h" +/* Output diagram + * FOR current evb, LOUT2 to speaker and LOUT2 to headphone + * DAC0(DAC_L_N/DAC_R_N)->HP_0 -> LOUT2 + * DAC1(DAC_L_P/DAC_R_P)->SP_0 -> LOUT1 + * + * FOR HP differential mode + *- DAC_L_N(DAC0) -> HP Driver -> LOUT2 ---------- + *- DAC_R_N(DAC0) -> HP Driver -> ROUT2 ---- | + * | | + * | R + * R | + * | | + *- DAC_L_P(DAC1) -> SPK Driver -> LOUT1 ---|----- + *- DAC_R_P(DAC1) -> SPK Driver -> ROUT1 --- + */ + enum rk730_mix_mode { RK730_MIX_MODE_1_PATH, RK730_MIX_MODE_2_PATHS, @@ -42,565 +57,554 @@ struct rk730_priv { }; /* ADC Digital Volume */ -static const DECLARE_TLV_DB_SCALE(adc_dig_tlv, -95625, 375, 0); +static const DECLARE_TLV_DB_MINMAX(adc_dig_tlv, -9600, 0); /* DAC Digital Volume */ -static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -95625, 375, 0); -/* D2S Volume */ -static const DECLARE_TLV_DB_SCALE(d2s_tlv, -1800, 300, 0); +static const DECLARE_TLV_DB_MINMAX(dac_dig_tlv, -9600, 0); /* ADC Volume */ -static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 300, 0); -/* MUX Volume */ -static const DECLARE_TLV_DB_SCALE(mux_tlv, -600, 600, 0); -/* MIX Buf Volume */ -static const DECLARE_TLV_DB_SCALE(mix_buf_tlv, -1800, 300, 0); -/* HP Volume */ -static const DECLARE_TLV_DB_SCALE(hp_tlv, 0, 300, 0); -/* LINEOUT Volume */ -static const DECLARE_TLV_DB_SCALE(lineout_tlv, 0, 300, 0); +static const DECLARE_TLV_DB_MINMAX(adc_tlv, -1050, 0); /* MIC Boost Volume */ static const DECLARE_TLV_DB_RANGE(micboost_tlv, 0, 2, TLV_DB_SCALE_ITEM(0, 600, 0), 3, 4, TLV_DB_SCALE_ITEM(2400, 1200, 0), 5, 7, TLV_DB_SCALE_ITEM(4200, 600, 0), - 8, 8, TLV_DB_SCALE_ITEM(-300, 0, 0), - 16, 16, TLV_DB_SCALE_ITEM(-600, 0, 0), - 24, 24, TLV_DB_SCALE_ITEM(-900, 0, 0) ); -static const char * const mux_out_l_text[] = { "DIFF", "MIC1N", "MIC2N" }; -static const char * const mux_out_r_text[] = { "DIFF", "MIC2P", "MIC1P" }; -static const char * const mux_input_l_text[] = { "DIFF", "VINP1", "VINN1" }; -static const char * const mux_input_r_text[] = { "DIFF", "VINP2", "VINN2" }; +static const DECLARE_TLV_DB_SCALE(micdecrease_tlv, 0, -300, 0); -static SOC_ENUM_SINGLE_DECL(mux_out_l_enum, RK730_MUXER_0, 2, mux_out_l_text); -static SOC_ENUM_SINGLE_DECL(mux_out_r_enum, RK730_MUXER_0, 6, mux_out_r_text); +static const char * const mux_input_l_text[] = { "DIFF", "VINR2", "VINL2" }; +static const char * const mux_input_r_text[] = { "DIFF", "VINR1", "VINL1" }; static SOC_ENUM_SINGLE_DECL(mux_input_l_enum, RK730_ADC_PGA_BLOCK_0, 4, mux_input_l_text); static SOC_ENUM_SINGLE_DECL(mux_input_r_enum, RK730_ADC_PGA_BLOCK_1, 4, mux_input_r_text); - -static const struct snd_kcontrol_new mux_out_l = - SOC_DAPM_ENUM("Left Out Mux", mux_out_l_enum); -static const struct snd_kcontrol_new mux_out_r = - SOC_DAPM_ENUM("Right Out Mux", mux_out_r_enum); static const struct snd_kcontrol_new mux_input_l = SOC_DAPM_ENUM("Left Input Mux", mux_input_l_enum); static const struct snd_kcontrol_new mux_input_r = SOC_DAPM_ENUM("Right Input Mux", mux_input_r_enum); -static const struct snd_kcontrol_new mix_ctls[] = { - SOC_DAPM_SINGLE("Left Out Mux Switch", RK730_MUXER_0, 0, 1, 1), - SOC_DAPM_SINGLE("Right Out Mux Switch", RK730_MUXER_0, 4, 1, 1), -}; +static const char * const adc_data_sel_text[] = { "normal", "left", "right", "swap" }; -static const char * const adc_hpf_cutoff_text[] = { - "3.79Hz", "60Hz", "243Hz", "493Hz", -}; - -static const char * const dac_hpf_cutoff_text[] = { - "80Hz", "100Hz", "120Hz", "140Hz", -}; - -static SOC_ENUM_SINGLE_DECL(adc_hpf_cutoff_enum, RK730_DADC_HPF, - 4, adc_hpf_cutoff_text); -static SOC_ENUM_SINGLE_DECL(dac_hpf_cutoff_enum, RK730_DDAC_MUTE_MIXCTL, - 5, dac_hpf_cutoff_text); +static SOC_ENUM_SINGLE_DECL(adc_data_sel_enum, RK730_DADC_SEL, + 0, adc_data_sel_text); +static const struct snd_kcontrol_new adc_data_sel = + SOC_DAPM_ENUM("ADCSel Mux", adc_data_sel_enum); static const char * const chop_freq_text[] = { "Disabled", "200kHz", "400kHz", "800kHz", }; -static SOC_ENUM_SINGLE_DECL(dac_ref_buf_chop_freq_enum, RK730_HK_TOP_1, - 6, chop_freq_text); +static const char * const hfp_center_freq_text[] = { + "80HZ", "100HZ", "120HZ", "140HZ", +}; + +static const char * const dac_hfp_center_freq_text[] = { + "C*0.8", "C*0.9", "C*1.0(fs=6.144M)", "C*1.1(fs=5.6448M)", + "C*1.2", "C*1.3", "C*1.4", "C*1.5(fs=4.096M)", +}; + static SOC_ENUM_SINGLE_DECL(mic_chop_freq_enum, RK730_MIC_BOOST_3, 6, chop_freq_text); static SOC_ENUM_SINGLE_DECL(adc_pga_chop_freq_enum, RK730_ADC_PGA_BLOCK_1, 6, chop_freq_text); -static SOC_ENUM_SINGLE_DECL(mux_out_chop_freq_enum, RK730_MUXER_1, - 0, chop_freq_text); -static SOC_ENUM_SINGLE_DECL(mix_chop_freq_enum, RK730_MIXER_2, - 6, chop_freq_text); static SOC_ENUM_SINGLE_DECL(hp_lo_chop_freq_enum, RK730_HP_1, 5, chop_freq_text); +static SOC_ENUM_SINGLE_DECL(dac_hfp_center_freq_enum, RK730_DDAC_FILTER, + 2, hfp_center_freq_text); + +static SOC_ENUM_SINGLE_DECL(adc_capacity_trim_enum, RK730_ADC_2, + 0, dac_hfp_center_freq_text); static const char * const micbias_volt_text[] = { "2.0v", "2.2v", "2.5v", "2.8v", }; -static const char * const charge_pump_volt_text[] = { - "2.1v", "2.3v", "2.5v", "2.7v", -}; - static SOC_ENUM_SINGLE_DECL(micbias_volt_enum, RK730_MIC_BIAS, 2, micbias_volt_text); -static SOC_ENUM_SINGLE_DECL(charge_pump_volt_enum, RK730_CHARGE_PUMP, - 1, charge_pump_volt_text); -static int rk730_adc_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int val = snd_soc_component_read(component, mc->reg); - unsigned int sign = snd_soc_component_read(component, RK730_DADC_SR_ACL); - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int shift = mc->shift; - int mid = mc->max / 2; - int uv; +static const char * const dig_ldo_volt_text[] = { + "1.4v", "1.5v", "1.6v", "1.7v", +}; - uv = (val >> shift) & mask; - sign &= RK730_DADC_SR_ACL_VOLL_POL_MASK; - if (sign) - uv = mid + uv; - else - uv = mid - uv; +static SOC_ENUM_SINGLE_DECL(dig_ldo_volt_enum, RK730_LDO, + 0, dig_ldo_volt_text); - ucontrol->value.integer.value[0] = uv; - ucontrol->value.integer.value[1] = uv; +static const char * const ana_ldo_volt_text[] = { + "1.4v", "1.5v", "1.6v", "1.7v", +}; - return 0; -} +static const struct snd_kcontrol_new rk730_out1_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); -static int rk730_adc_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int val, val_mask, sign, sign_mask; - int uv = ucontrol->value.integer.value[0]; - int min = mc->min; - int mid = mc->max / 2; +static const struct snd_kcontrol_new rk730_out2_switch = + SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0); - sign_mask = RK730_DADC_SR_ACL_VOLL_POL_MASK | RK730_DADC_SR_ACL_VOLR_POL_MASK; - - if (uv > mid) { - sign = RK730_DADC_SR_ACL_VOLL_POS | RK730_DADC_SR_ACL_VOLR_POS; - uv = uv - mid; - } else { - sign = RK730_DADC_SR_ACL_VOLL_NEG | RK730_DADC_SR_ACL_VOLR_NEG; - uv = mid - uv; - } - - val = ((uv + min) & mask); - val_mask = mask << shift; - val = val << shift; - - snd_soc_component_update_bits(component, reg, val_mask, val); - snd_soc_component_update_bits(component, rreg, val_mask, val); - snd_soc_component_update_bits(component, RK730_DADC_SR_ACL, sign_mask, sign); - - return 1; -} - -static int rk730_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int val = snd_soc_component_read(component, mc->reg); - unsigned int sign = snd_soc_component_read(component, RK730_DDAC_SR_LMT); - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int shift = mc->shift; - int mid = mc->max / 2; - int uv; - - uv = (val >> shift) & mask; - sign &= RK730_DDAC_SR_LMT_VOLL_POL_MASK; - if (sign) - uv = mid + uv; - else - uv = mid - uv; - - ucontrol->value.integer.value[0] = uv; - ucontrol->value.integer.value[1] = uv; - - return 0; -} - -static int rk730_dac_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - unsigned int reg = mc->reg; - unsigned int rreg = mc->rreg; - unsigned int shift = mc->shift; - unsigned int mask = (1 << fls(mc->max)) - 1; - unsigned int val, val_mask, sign, sign_mask; - int uv = ucontrol->value.integer.value[0]; - int min = mc->min; - int mid = mc->max / 2; - - sign_mask = RK730_DDAC_SR_LMT_VOLL_POL_MASK | RK730_DDAC_SR_LMT_VOLR_POL_MASK; - - if (uv > mid) { - sign = RK730_DDAC_SR_LMT_VOLL_POS | RK730_DDAC_SR_LMT_VOLR_POS; - uv = uv - mid; - } else { - sign = RK730_DDAC_SR_LMT_VOLL_NEG | RK730_DDAC_SR_LMT_VOLR_NEG; - uv = mid - uv; - } - - val = ((uv + min) & mask); - val_mask = mask << shift; - val = val << shift; - - snd_soc_component_update_bits(component, reg, val_mask, val); - snd_soc_component_update_bits(component, rreg, val_mask, val); - snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT, sign_mask, sign); - - return 1; -} - -static int rk730_cp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - usleep_range(5000, 5100); - - return 0; -} +static SOC_ENUM_SINGLE_DECL(ana_ldo_volt_enum, RK730_LDO, + 4, ana_ldo_volt_text); static int rk730_pll_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - if (SND_SOC_DAPM_EVENT_ON(event)) + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); snd_soc_component_write(component, RK730_SYSPLL_0, 0x00); - else - snd_soc_component_write(component, RK730_SYSPLL_0, 0xff); - - return 0; -} - -static int rk730_adc_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - - if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_component_update_bits(component, RK730_ADC_0, - RK730_ADC_0_DEM_EN_MASK, - RK730_ADC_0_DEM_EN); - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN | - RK730_DTOP_DIGEN_CLKE_ADC_EN | - RK730_DTOP_DIGEN_CLKE_I2STX_EN); - usleep_range(20000, 21000); - snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD, - RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, - RK730_DI2S_TXCR_3_TXCMD_TXS_EN); } else { - snd_soc_component_update_bits(component, RK730_DI2S_TXCR_3_TXCMD, - RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, - RK730_DI2S_TXCR_3_TXCMD_TXS_DIS); - snd_soc_component_update_bits(component, RK730_ADC_0, - RK730_ADC_0_DEM_EN_MASK, - RK730_ADC_0_DEM_DIS); - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_ADC_DIS | - RK730_DTOP_DIGEN_CLKE_I2STX_DIS); + dev_dbg(component->dev, "%s off\n", __func__); + snd_soc_component_write(component, RK730_SYSPLL_0, 0xff); } - return 0; } -static int rk730_dac_event(struct snd_soc_dapm_widget *w, +static int rk730_dacl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - if (SND_SOC_DAPM_EVENT_ON(event)) { - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN | - RK730_DTOP_DIGEN_CLKE_DAC_EN | - RK730_DTOP_DIGEN_CLKE_I2SRX_EN); + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_out1_drv_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_out2_drv_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_dacr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} + +static int rk730_sdin_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + dev_dbg(component->dev, "%s on\n", __func__); snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD, RK730_DI2S_RXCMD_TSD_RXS_MASK, RK730_DI2S_RXCMD_TSD_RXS_EN); - } else { + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_EN | + RK730_DTOP_DIGEN_CLKE_I2SRX_EN); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_EN | + RK730_DTOP_DIGEN_CLKE_DAC_EN); + break; + case SND_SOC_DAPM_POST_PMD: + dev_dbg(component->dev, "%s off\n", __func__); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK, + RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS | + RK730_DTOP_DIGEN_CLKE_DAC_DIS); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS | + RK730_DTOP_DIGEN_CLKE_I2SRX_DIS); snd_soc_component_update_bits(component, RK730_DI2S_RXCMD_TSD, RK730_DI2S_RXCMD_TSD_RXS_MASK, RK730_DI2S_RXCMD_TSD_RXS_DIS); - snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_MASK | - RK730_DTOP_DIGEN_CLKE_DAC_EN_MASK | - RK730_DTOP_DIGEN_CLKE_I2SRX_EN_MASK, - RK730_DTOP_DIGEN_CLKE_DAC_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_I2SRX_CKE_DIS | - RK730_DTOP_DIGEN_CLKE_DAC_DIS | - RK730_DTOP_DIGEN_CLKE_I2SRX_DIS); + break; + default: + dev_err(component->dev, "%s Invalid event = 0x%x\n", __func__, event); } - return 0; } -static int rk730_mux_out_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int rk730_sdout_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR3_TXCMD, + RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, + RK730_DI2S_TXCR_3_TXCMD_TXS_EN); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_EN | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_EN); + usleep_range(20000, 21000); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_EN | + RK730_DTOP_DIGEN_CLKE_I2STX_EN); + } else { + dev_dbg(component->dev, "%s off\n", __func__); + + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_EN_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_EN_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_DIS | + RK730_DTOP_DIGEN_CLKE_I2STX_DIS); + usleep_range(50, 60); + snd_soc_component_update_bits(component, RK730_DTOP_DIGEN_CLKE, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_MASK | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_MASK, + RK730_DTOP_DIGEN_CLKE_ADC_CKE_DIS | + RK730_DTOP_DIGEN_CLKE_I2STX_CKE_DIS); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR3_TXCMD, + RK730_DI2S_TXCR_3_TXCMD_TXS_MASK, + RK730_DI2S_TXCR_3_TXCMD_TXS_DIS); + } + return 0; +} + +static int rk730_adcr_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_dbg(component->dev, "%s on\n", __func__); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_dbg(component->dev, "%s off\n", __func__); + break; + default: + dev_err(component->dev, "%s Invalid event = 0x%x\n", __func__, event); + } + return 0; +} + +static int rk730_adcl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + dev_dbg(component->dev, "%s on\n", __func__); + break; + case SND_SOC_DAPM_PRE_PMD: + dev_dbg(component->dev, "%s off\n", __func__); + break; + default: + dev_err(component->dev, "%s Invalid event = 0x%x\n", __func__, event); + } + return 0; +} + +static int rk730_dac0_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_DAC_0, + RK730_DAC_0_DAC_R_HP_PWD_MASK | + RK730_DAC_0_DAC_L_HP_PWD_MASK | + RK730_DAC_0_DAC_HP_IBIAS_MASK, + RK730_DAC_0_DAC_L_HP_PWU | + RK730_DAC_0_DAC_R_HP_PWU | + RK730_DAC_0_DAC_HP_IBIAS_ON); + snd_soc_component_update_bits(component, RK730_HP_0, + RK730_HP_0_ANTIPOP_PWR_MASK | + RK730_HP_0_HP_IBIAS_MASK | + RK730_HP_0_HP_TWOTAGE_EN_MASK | + RK730_HP_0_HP_OSTG_PWR_MASK | + RK730_HP_0_HP_BLOCK_PWR_MASK, + RK730_HP_0_ANTIPOP_PWR_OFF | + RK730_HP_0_HP_IBIAS_ON | + RK730_HP_0_HP_TWOTAGE_EN | + RK730_HP_0_HP_OSTG_PWR_ON | + RK730_HP_0_HP_BLOCK_PWR_ON); + } else { + dev_dbg(component->dev, "%s off\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_HP_0, + RK730_HP_0_ANTIPOP_PWR_MASK | + RK730_HP_0_HP_IBIAS_MASK | + RK730_HP_0_HP_TWOTAGE_EN_MASK | + RK730_HP_0_HP_OSTG_PWR_MASK | + RK730_HP_0_HP_BLOCK_PWR_MASK, + RK730_HP_0_ANTIPOP_PWR_ON | + RK730_HP_0_HP_IBIAS_OFF | + RK730_HP_0_HP_TWOTAGE_DIS | + RK730_HP_0_HP_OSTG_PWR_OFF | + RK730_HP_0_HP_BLOCK_PWR_OFF); + snd_soc_component_update_bits(component, RK730_DAC_0, + RK730_DAC_0_DAC_R_HP_PWD_MASK | + RK730_DAC_0_DAC_L_HP_PWD_MASK | + RK730_DAC_0_DAC_HP_IBIAS_MASK, + RK730_DAC_0_DAC_L_HP_PWD | + RK730_DAC_0_DAC_R_HP_PWD| + RK730_DAC_0_DAC_HP_IBIAS_OFF); + } + return 0; +} + +static int rk730_dac1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) { + dev_dbg(component->dev, "%s on\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_DAC_1, + RK730_DAC_1_DAC_SPK_IBIAS_MASK | + RK730_DAC_1_DAC_R_SPK_PWD_MASK | + RK730_DAC_1_DAC_L_SPK_PWD_MASK, + RK730_DAC_1_DAC_SPK_IBIAS_ON | + RK730_DAC_1_DAC_R_SPK_PWU | + RK730_DAC_1_DAC_L_SPK_PWU); + snd_soc_component_update_bits(component, RK730_SPK_0, + RK730_SPK_0_ANTIPOP_PWR_MASK | + RK730_SPK_0_SPK_IBIAS_MASK | + RK730_SPK_0_SPK_OSTAGE_PWR_MASK | + RK730_SPK_0_SPK_BLOCK_PWR_MASK, + RK730_SPK_0_ANTIPOP_PWR_OFF | + RK730_SPK_0_SPK_IBIAS_ON | + RK730_SPK_0_SPK_OSTAGE_PWR_ON | + RK730_SPK_0_SPK_BLOCK_PWR_ON); + } else { + dev_dbg(component->dev, "%s off\n", __func__); + + /* analog config */ + snd_soc_component_update_bits(component, RK730_SPK_0, + RK730_SPK_0_ANTIPOP_PWR_MASK | + RK730_SPK_0_SPK_IBIAS_MASK | + RK730_SPK_0_SPK_OSTAGE_PWR_MASK | + RK730_SPK_0_SPK_BLOCK_PWR_MASK, + RK730_SPK_0_ANTIPOP_PWR_ON | + RK730_SPK_0_SPK_IBIAS_OFF | + RK730_SPK_0_SPK_OSTAGE_PWR_OFF | + RK730_SPK_0_SPK_BLOCK_PWR_OFF); + snd_soc_component_update_bits(component, RK730_DAC_1, + RK730_DAC_1_DAC_SPK_IBIAS_MASK | + RK730_DAC_1_DAC_R_SPK_PWD_MASK | + RK730_DAC_1_DAC_L_SPK_PWD_MASK, + RK730_DAC_1_DAC_SPK_IBIAS_OFF | + RK730_DAC_1_DAC_R_SPK_PWD | + RK730_DAC_1_DAC_L_SPK_PWD); + } + return 0; +} + +static int rk730_out1_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component); - unsigned int val; if (SND_SOC_DAPM_EVENT_ON(event)) - val = atomic_inc_return(&rk730->mix_mode); + dev_dbg(component->dev, "%s on\n", __func__); else - val = atomic_dec_return(&rk730->mix_mode); + dev_dbg(component->dev, "%s off\n", __func__); + return 0; +} - snd_soc_component_update_bits(component, RK730_MIXER_2, - RK730_MIXER_2_MIX_R_MODE_MASK | - RK730_MIXER_2_MIX_L_MODE_MASK, - RK730_MIXER_2_MIX_R_MODE(val) | - RK730_MIXER_2_MIX_L_MODE(val)); +static int rk730_out2_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + dev_dbg(component->dev, "%s on\n", __func__); + else + dev_dbg(component->dev, "%s off\n", __func__); return 0; } static const struct snd_kcontrol_new rk730_snd_controls[] = { - SOC_DOUBLE_R_TLV("ADC Volume", RK730_ADC_PGA_BLOCK_0, RK730_ADC_PGA_BLOCK_1, + SOC_DOUBLE_R_TLV("ADC PGA Volume", RK730_ADC_PGA_BLOCK_0, RK730_ADC_PGA_BLOCK_1, 1, 0x7, 1, adc_tlv), - SOC_DOUBLE_R_TLV("D2S Volume", RK730_DAC_1, RK730_DAC_2, - 1, 0x6, 1, d2s_tlv), - - SOC_DOUBLE_R_TLV("MIC1 Boost Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1, - 1, 0x18, 0, micboost_tlv), - SOC_DOUBLE_R_TLV("MIC2 Boost Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3, - 1, 0x18, 0, micboost_tlv), - - SOC_DOUBLE_TLV("Out Mux Volume", RK730_MUXER_0, 1, 5, 0x1, 0, mux_tlv), - - SOC_SINGLE_TLV("Left Out Mux -> Left Out Mixer Volume", - RK730_MIXER_0, 1, 0x6, 1, mix_buf_tlv), - SOC_SINGLE_TLV("Left Out Mux -> Right Out Mixer Volume", - RK730_MIXER_0, 5, 0x6, 1, mix_buf_tlv), - SOC_SINGLE_TLV("Right Out Mux -> Left Out Mixer Volume", - RK730_MIXER_1, 1, 0x6, 1, mix_buf_tlv), - SOC_SINGLE_TLV("Right Out Mux -> Right Out Mixer Volume", - RK730_MIXER_1, 5, 0x6, 1, mix_buf_tlv), - - SOC_SINGLE_TLV("HP Volume", RK730_HP_0, 6, 0x3, 0, hp_tlv), - SOC_SINGLE_TLV("Line Out Volume", RK730_LINEOUT_1, 2, 0x3, 0, lineout_tlv), - - SOC_DOUBLE_R_EXT_TLV("ADC Digital Volume", - RK730_DADC_VOLL, RK730_DADC_VOLR, 0, 0x1fe, 0, - rk730_adc_vol_get, - rk730_adc_vol_put, - adc_dig_tlv), - SOC_DOUBLE_R_EXT_TLV("DAC Digital Volume", - RK730_DDAC_VOLL, RK730_DDAC_VOLR, 0, 0x1fe, 0, - rk730_dac_vol_get, - rk730_dac_vol_put, - dac_dig_tlv), - - SOC_ENUM("ADC HPF Cutoff", adc_hpf_cutoff_enum), - SOC_ENUM("DAC HPF Cutoff", dac_hpf_cutoff_enum), - SOC_ENUM("DAC Ref Buf Chop Freq", dac_ref_buf_chop_freq_enum), + SOC_DOUBLE_R_TLV("MIC2 Boost Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1, + 1, 0x7, 0, micboost_tlv), + SOC_DOUBLE_R_TLV("MIC1 Boost Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3, + 1, 0x7, 0, micboost_tlv), + SOC_DOUBLE_R_TLV("MIC2 decrease Volume", RK730_MIC_BOOST_0, RK730_MIC_BOOST_1, + 4, 0x3, 0, micdecrease_tlv), + SOC_DOUBLE_R_TLV("MIC1 decrease Volume", RK730_MIC_BOOST_2, RK730_MIC_BOOST_3, + 4, 0x3, 0, micdecrease_tlv), + SOC_DOUBLE_R_TLV("ADC Digital Volume", RK730_DADC_VOLL, RK730_DADC_VOLR, + 0, 0xff, 1, adc_dig_tlv), + SOC_DOUBLE_R_TLV("DAC Digital Volume", RK730_DDAC_VOLL, RK730_DDAC_VOLR, + 0, 0xff, 1, dac_dig_tlv), + SOC_ENUM("DIG DLO VOLTAGE", dig_ldo_volt_enum), + SOC_ENUM("ANA DLO VOLTAGE", ana_ldo_volt_enum), SOC_ENUM("MIC Chop Freq", mic_chop_freq_enum), SOC_ENUM("ADC PGA Chop Freq", adc_pga_chop_freq_enum), - SOC_ENUM("Out Mux Chop Freq", mux_out_chop_freq_enum), - SOC_ENUM("Mixer Chop Freq", mix_chop_freq_enum), SOC_ENUM("HP / Lineout Chop Freq", hp_lo_chop_freq_enum), SOC_ENUM("Mic Bias Volt", micbias_volt_enum), - SOC_ENUM("Charge Pump Volt", charge_pump_volt_enum), - - SOC_SINGLE("ADCL HPF Switch", RK730_DADC_HPF, 7, 1, 0), - SOC_SINGLE("ADCR HPF Switch", RK730_DADC_HPF, 6, 1, 0), - SOC_SINGLE("DAC HPF Switch", RK730_DDAC_MUTE_MIXCTL, 7, 1, 0), + SOC_ENUM("DAC HPF Center Freq", dac_hfp_center_freq_enum), + SOC_ENUM("ADC CAPACITY TRIM", adc_capacity_trim_enum), SOC_SINGLE("ADC Volume Bypass Switch", RK730_DTOP_VUCTL, 7, 1, 0), SOC_SINGLE("DAC Volume Bypass Switch", RK730_DTOP_VUCTL, 6, 1, 0), SOC_SINGLE("ADC Fade Switch", RK730_DTOP_VUCTL, 5, 1, 0), SOC_SINGLE("DAC Fade Switch", RK730_DTOP_VUCTL, 4, 1, 0), + SOC_SINGLE("DAC Left gain polarity", RK730_DTOP_VUCTL, 3, 1, 0), + SOC_SINGLE("DAC Right gain polarity", RK730_DTOP_VUCTL, 2, 1, 0), SOC_SINGLE("ADC Zero Crossing Switch", RK730_DTOP_VUCTL, 1, 1, 0), SOC_SINGLE("DAC Zero Crossing Switch", RK730_DTOP_VUCTL, 0, 1, 0), SOC_SINGLE("MIC1N / MIC2P Exchanged Switch", RK730_MIC_BOOST_2, 7, 1, 0), + SOC_SINGLE("ADC CHOP EN", RK730_ADC_2, 4, 1, 0), }; static const struct snd_soc_dapm_widget rk730_dapm_widgets[] = { - SND_SOC_DAPM_SUPPLY_S("ANA LDO", 0, RK730_LDO, 7, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("OSC CLK", 1, RK730_HK_TOP_2, 4, 0, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("VAG BUF", 1, RK730_HK_TOP_2, 2, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("ADC BUF", 1, RK730_HK_TOP_2, 1, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("DAC BUF", 1, RK730_HK_TOP_2, 0, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("MICBIAS", 1, RK730_MIC_BIAS, 0, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("Charge Pump", 1, RK730_CHARGE_PUMP, 0, 0, - rk730_cp_event, SND_SOC_DAPM_POST_PMU), - SND_SOC_DAPM_SUPPLY_S("PLL", 2, SND_SOC_NOPM, 0, 0, rk730_pll_event, + SND_SOC_DAPM_SUPPLY_S("ANA LDO", 1, RK730_LDO, 7, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("PLL", 1, SND_SOC_NOPM, 0, 0, + rk730_pll_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_SUPPLY_S("DAC Bias", 2, RK730_DAC_0, 2, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("HP Bias", 2, RK730_HP_0, 5, 1, NULL, 0), - SND_SOC_DAPM_SUPPLY_S("Line Out Bias", 2, RK730_LINEOUT_1, 7, 1, NULL, 0), - - SND_SOC_DAPM_ADC_E("ADCL", "HiFi Capture", RK730_ADC_0, 0, 1, - rk730_adc_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_ADC_E("ADCR", "HiFi Capture", RK730_ADC_0, 1, 1, - rk730_adc_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_DAC_E("DACL", "HiFi Playback", RK730_DAC_0, 0, 1, - rk730_dac_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_DAC_E("DACR", "HiFi Playback", RK730_DAC_0, 1, 1, - rk730_dac_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_PGA("ADCL PGA", RK730_ADC_PGA_BLOCK_0, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("ADCR PGA", RK730_ADC_PGA_BLOCK_1, 0, 1, NULL, 0), - - SND_SOC_DAPM_PGA("D2SL", RK730_DAC_1, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("D2SR", RK730_DAC_2, 0, 1, NULL, 0), - - SND_SOC_DAPM_PGA("MIC1P", RK730_MIC_BOOST_0, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("MIC1N", RK730_MIC_BOOST_1, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("MIC2P", RK730_MIC_BOOST_2, 0, 1, NULL, 0), - SND_SOC_DAPM_PGA("MIC2N", RK730_MIC_BOOST_3, 0, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DAC BUF", 2, RK730_HK_TOP_2, 0, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("HK VAG BUF", 0, RK730_HK_TOP_1, 7, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("HK DAC BUF", 0, RK730_HK_TOP_1, 6, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("MICBIAS", 1, RK730_MIC_BIAS, 0, 1, NULL, 0), + SND_SOC_DAPM_DAC_E("DAC0", NULL, SND_SOC_NOPM, 0, 0, + rk730_dac0_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("DAC1", NULL, SND_SOC_NOPM, 0, 0, + rk730_dac1_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("DACL", "Left Playback", SND_SOC_NOPM, 0, 0, + rk730_dacl_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_DAC_E("DACR", "Right Playback", SND_SOC_NOPM, 0, 0, + rk730_dacr_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("OUT1 Power", SND_SOC_NOPM, 0, 0, + rk730_out1_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("OUT2 Power", SND_SOC_NOPM, 0, 0, + rk730_out2_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SWITCH("OUT1", SND_SOC_NOPM, 0, 0, &rk730_out1_switch), + SND_SOC_DAPM_SWITCH("OUT2", SND_SOC_NOPM, 0, 0, &rk730_out2_switch), + SND_SOC_DAPM_OUT_DRV_E("OUT1 DRV", SND_SOC_NOPM, 0, 0, NULL, 0, rk730_out1_drv_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUT_DRV_E("OUT2 DRV", SND_SOC_NOPM, 0, 0, NULL, 0, rk730_out2_drv_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_OUTPUT("LOUT1"), + SND_SOC_DAPM_OUTPUT("ROUT1"), + SND_SOC_DAPM_OUTPUT("LOUT2"), + SND_SOC_DAPM_OUTPUT("ROUT2"), + SND_SOC_DAPM_AIF_IN_E("I2S IN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0, + rk730_sdin_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("I2S OUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0, + rk730_sdout_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_ADC_E("ADCL", "Left Capture", RK730_ADC_0, 0, 1, + rk730_adcl_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_ADC_E("ADCR", "Right Capture", RK730_ADC_0, 1, 1, + rk730_adcr_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_MUX("ADCSel Mux", SND_SOC_NOPM, 0, 1, &adc_data_sel), + SND_SOC_DAPM_MUX("Left PGA Mux", RK730_ADC_PGA_BLOCK_0, 0, 1, &mux_input_l), + SND_SOC_DAPM_MUX("Right PGA Mux", RK730_ADC_PGA_BLOCK_1, 0, 1, &mux_input_r), + /* 0:mic_r2_pwd 3:1 mic_r2_boost */ + SND_SOC_DAPM_PGA("MIC2R", RK730_MIC_BOOST_0, 0, 1, NULL, 0), + SND_SOC_DAPM_PGA("MIC2L", RK730_MIC_BOOST_1, 0, 1, NULL, 0), + SND_SOC_DAPM_PGA("MIC1R", RK730_MIC_BOOST_2, 0, 1, NULL, 0), + SND_SOC_DAPM_PGA("MIC1L", RK730_MIC_BOOST_3, 0, 1, NULL, 0), SND_SOC_DAPM_PGA("DIFFL", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("DIFFR", SND_SOC_NOPM, 0, 0, NULL, 0), - - SND_SOC_DAPM_PGA("HP Out", RK730_HP_0, 2, 1, NULL, 0), - SND_SOC_DAPM_PGA("HP Out Stage", RK730_HP_0, 3, 1, NULL, 0), - SND_SOC_DAPM_PGA("Line Out", RK730_LINEOUT_0, 2, 1, NULL, 0), - SND_SOC_DAPM_PGA("Line Out Stage", RK730_LINEOUT_0, 3, 1, NULL, 0), - - SND_SOC_DAPM_MUX_E("Left Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_l, - rk730_mux_out_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX_E("Right Out Mux", SND_SOC_NOPM, 0, 0, &mux_out_r, - rk730_mux_out_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - - SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_l), - SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &mux_input_r), - - SND_SOC_DAPM_MIXER("Left Out Mixer", RK730_MIXER_2, 0, 1, - mix_ctls, ARRAY_SIZE(mix_ctls)), - SND_SOC_DAPM_MIXER("Right Out Mixer", RK730_MIXER_2, 3, 1, - mix_ctls, ARRAY_SIZE(mix_ctls)), - - SND_SOC_DAPM_OUTPUT("HPL"), - SND_SOC_DAPM_OUTPUT("HPR"), - SND_SOC_DAPM_OUTPUT("LINEOUTL"), - SND_SOC_DAPM_OUTPUT("LINEOUTR"), - SND_SOC_DAPM_INPUT("MIC1"), SND_SOC_DAPM_INPUT("MIC2"), }; static const struct snd_soc_dapm_route rk730_dapm_routes[] = { - { "DACL", NULL, "ANA LDO" }, - { "DACR", NULL, "ANA LDO" }, - { "DACL", NULL, "OSC CLK" }, - { "DACR", NULL, "OSC CLK" }, - { "DACL", NULL, "VAG BUF" }, - { "DACR", NULL, "VAG BUF" }, - { "DACL", NULL, "DAC BUF" }, - { "DACR", NULL, "DAC BUF" }, - { "DACL", NULL, "PLL" }, - { "DACR", NULL, "PLL" }, - { "DACL", NULL, "DAC Bias" }, - { "DACR", NULL, "DAC Bias" }, + {"OUT1", NULL, "OUT1 Power"}, + {"OUT2", NULL, "OUT2 Power"}, - { "D2SL", NULL, "DACL" }, - { "D2SR", NULL, "DACR" }, + {"LOUT1", NULL, "OUT1 DRV"}, + {"ROUT1", NULL, "OUT1 DRV"}, + {"LOUT2", NULL, "OUT2 DRV"}, + {"ROUT2", NULL, "OUT2 DRV"}, - { "Left Out Mixer", NULL, "D2SL" }, - { "Left Out Mixer", "Left Out Mux Switch", "Left Out Mux" }, - { "Left Out Mixer", "Right Out Mux Switch", "Right Out Mux" }, - { "Right Out Mixer", NULL, "D2SR" }, - { "Right Out Mixer", "Left Out Mux Switch", "Left Out Mux" }, - { "Right Out Mixer", "Right Out Mux Switch", "Right Out Mux" }, + {"OUT1 DRV", NULL, "OUT1"}, + {"OUT2 DRV", NULL, "OUT2"}, - { "Left Out Mux", "DIFF", "DIFFL" }, - { "Left Out Mux", "MIC1N", "MIC1N" }, - { "Left Out Mux", "MIC2N", "MIC2N" }, + {"OUT1", "Switch", "DAC1"}, + {"OUT2", "Switch", "DAC0"}, - { "Right Out Mux", "DIFF", "DIFFR" }, - { "Right Out Mux", "MIC1P", "MIC1P" }, - { "Right Out Mux", "MIC2P", "MIC2P" }, + {"DAC1", NULL, "I2S IN"}, + {"DAC0", NULL, "I2S IN"}, - { "HP Out", NULL, "HP Bias" }, - { "HP Out", NULL, "HP Bias" }, - { "Line Out", NULL, "Line Out Bias" }, + {"HK DAC BUF", NULL, "HK VAG BUF"}, + {"I2S IN", NULL, "HK DAC BUF"}, + {"I2S OUT", NULL, "HK VAG BUF"}, + {"I2S IN", NULL, "PLL"}, + {"I2S OUT", NULL, "PLL"}, + {"I2S IN", NULL, "ANA LDO"}, + {"I2S OUT", NULL, "ANA LDO"}, - { "HP Out", NULL, "Left Out Mixer" }, - { "HP Out", NULL, "Right Out Mixer" }, - { "Line Out", NULL, "Left Out Mixer" }, - { "Line Out", NULL, "Right Out Mixer" }, + {"I2S OUT", NULL, "ADCR"}, + {"I2S OUT", NULL, "ADCL"}, + {"ADCR", NULL, "ADCSel Mux"}, + {"ADCL", NULL, "ADCSel Mux"}, - { "HP Out Stage", NULL, "HP Out" }, - { "Line Out Stage", NULL, "Line Out" }, + {"ADCSel Mux", "normal", "Left PGA Mux"}, + {"ADCSel Mux", "normal", "Right PGA Mux"}, + {"ADCSel Mux", "swap", "Left PGA Mux"}, + {"ADCSel Mux", "swap", "Right PGA Mux"}, + {"ADCSel Mux", "left", "Left PGA Mux"}, + {"ADCSel Mux", "right", "Right PGA Mux"}, - { "HPL", NULL, "HP Out Stage" }, - { "HPR", NULL, "HP Out Stage" }, - { "HPL", NULL, "Charge Pump" }, - { "HPR", NULL, "Charge Pump" }, + {"Left PGA Mux", "DIFF", "DIFFL"}, + {"Left PGA Mux", "VINR2", "MIC2R"}, + {"Left PGA Mux", "VINL2", "MIC2L"}, - { "LINEOUTL", NULL, "Line Out Stage" }, - { "LINEOUTR", NULL, "Line Out Stage" }, - { "LINEOUTL", NULL, "Charge Pump" }, - { "LINEOUTR", NULL, "Charge Pump" }, + {"Right PGA Mux", "DIFF", "DIFFR"}, + {"Right PGA Mux", "VINR1", "MIC1R"}, + {"Right PGA Mux", "VINL1", "MIC1L"}, - { "ADCL", NULL, "ANA LDO" }, - { "ADCR", NULL, "ANA LDO" }, - { "ADCL", NULL, "OSC CLK" }, - { "ADCR", NULL, "OSC CLK" }, - { "ADCL", NULL, "ADC BUF" }, - { "ADCR", NULL, "ADC BUF" }, - { "ADCL", NULL, "VAG BUF" }, - { "ADCR", NULL, "VAG BUF" }, - { "ADCL", NULL, "PLL" }, - { "ADCR", NULL, "PLL" }, + {"DIFFL", NULL, "MIC2R"}, + {"DIFFL", NULL, "MIC2L"}, + {"DIFFR", NULL, "MIC1R"}, + {"DIFFR", NULL, "MIC1L"}, - { "ADCL", NULL, "ADCL PGA" }, - { "ADCR", NULL, "ADCR PGA" }, - { "ADCL PGA", NULL, "Left Input Mux" }, - { "ADCR PGA", NULL, "Right Input Mux" }, - - { "Left Input Mux", "DIFF", "DIFFL" }, - { "Left Input Mux", "VINP1", "MIC1P" }, - { "Left Input Mux", "VINN1", "MIC1N" }, - { "Right Input Mux", "DIFF", "DIFFR" }, - { "Right Input Mux", "VINP2", "MIC2P" }, - { "Right Input Mux", "VINN2", "MIC2N" }, - - { "DIFFL", NULL, "MIC1P" }, - { "DIFFL", NULL, "MIC1N" }, - { "DIFFR", NULL, "MIC2P" }, - { "DIFFR", NULL, "MIC2N" }, - - { "MIC1P", NULL, "MIC1" }, - { "MIC1N", NULL, "MIC1" }, - { "MIC2P", NULL, "MIC2" }, - { "MIC2N", NULL, "MIC2" }, - - { "MIC1", NULL, "MICBIAS" }, - { "MIC2", NULL, "MICBIAS" }, + {"MIC1R", NULL, "MIC1"}, + {"MIC1L", NULL, "MIC1"}, + {"MIC2R", NULL, "MIC2"}, + {"MIC2L", NULL, "MIC2"}, + {"MIC1", NULL, "MICBIAS"}, + {"MIC2", NULL, "MICBIAS"}, }; static unsigned int samplerate_to_bit(unsigned int samplerate) @@ -636,64 +640,134 @@ static int rk730_dai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; - unsigned int width, rate; + unsigned int rate; - width = min(params_width(params), 24); - rate = samplerate_to_bit(params_rate(params)); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_soc_component_update_bits(component, RK730_DI2S_RXCR_2, - RK730_DI2S_XCR2_VDW_MASK, - RK730_DI2S_XCR2_VDW(width)); - snd_soc_component_update_bits(component, RK730_DDAC_SR_LMT, - RK730_DDAC_SR_LMT_SRT_MASK, - RK730_DDAC_SR_LMT_SRT(rate)); - } else { - snd_soc_component_update_bits(component, RK730_DI2S_TXCR_2, - RK730_DI2S_XCR2_VDW_MASK, - RK730_DI2S_XCR2_VDW(width)); - snd_soc_component_update_bits(component, RK730_DADC_SR_ACL, - RK730_DADC_SR_ACL_SRT_MASK, - RK730_DADC_SR_ACL_SRT(rate)); + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(16)); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(16)); + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S32_LE: + snd_soc_component_update_bits(component, RK730_DI2S_RXCR2, + RK730_DI2S_RXCR2_VDW_MASK, + RK730_DI2S_RXCR2_VDW(24)); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR2, + RK730_DI2S_TXCR2_VDW_MASK, + RK730_DI2S_TXCR2_VDW(24)); + break; + default: + return -EINVAL; } + rate = samplerate_to_bit(params_rate(params)); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + snd_soc_component_update_bits(component, RK730_DTOP_SRT, + RK730_DTOP_DACSRT_MASK, + RK730_DTOP_DACSRT(rate)); + } else { + snd_soc_component_update_bits(component, RK730_DTOP_SRT, + RK730_DTOP_ADCSRT_MASK, + RK730_DTOP_ADCSRT(rate)); + } return 0; } static int rk730_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_component *component = codec_dai->component; + u8 val = 0, format = 0; + u8 mask = RK730_DI2S_TXCR1_TFS_TX_MASK; + int ret = 0; - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - snd_soc_component_update_bits(component, RK730_DI2S_CKM, - RK730_DI2S_CKM_MST_MASK, - RK730_DI2S_CKM_MST_SLAVE); + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + mask |= RK730_DI2S_TXCR1_IBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_I2S | RK730_DI2S_TXCR1_IBM_TX_NORMAL; break; - case SND_SOC_DAIFMT_CBM_CFM: - snd_soc_component_update_bits(component, RK730_DI2S_CKM, - RK730_DI2S_CKM_MST_MASK, - RK730_DI2S_CKM_MST_MASTER); + case SND_SOC_DAIFMT_RIGHT_J: + mask |= RK730_DI2S_TXCR1_IBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_I2S | RK730_DI2S_TXCR1_IBM_TX_RIGHT; + break; + case SND_SOC_DAIFMT_LEFT_J: + mask |= RK730_DI2S_TXCR1_PBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_I2S | RK730_DI2S_TXCR1_IBM_TX_LEFT; + break; + case SND_SOC_DAIFMT_DSP_A: + mask |= RK730_DI2S_TXCR1_PBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_PCM | RK730_DI2S_TXCR1_PBM_TX_NODELAY; + break; + case SND_SOC_DAIFMT_DSP_B: + mask |= RK730_DI2S_TXCR1_PBM_TX_MASK; + format = RK730_DI2S_TXCR1_TFS_TX_PCM | RK730_DI2S_TXCR1_PBM_TX_DELAY1; break; default: return -EINVAL; } + snd_soc_component_update_bits(component, RK730_DI2S_RXCR1, mask, format); + snd_soc_component_update_bits(component, RK730_DI2S_TXCR1, mask, format); - return 0; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_NF: + val |= RK730_DI2S_CKM_SCLK_INVERTED; + break; + case SND_SOC_DAIFMT_NB_NF: + val |= RK730_DI2S_CKM_SCLK_NORMAL; + break; + default: + ret = -EINVAL; + } + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + val |= RK730_DI2S_CKM_MST_SLAVE | RK730_DI2S_CKM_SCLK_DIS; + break; + case SND_SOC_DAIFMT_CBM_CFM: + val |= RK730_DI2S_CKM_MST_MASTER | RK730_DI2S_CKM_SCLK_EN; + break; + default: + return -EINVAL; + } + snd_soc_component_update_bits(component, RK730_DI2S_CKM, + RK730_DI2S_CKM_MST_MASK | + RK730_DI2S_CKM_SCLK_POL_MASK | + RK730_DI2S_CKM_SCLK_EN_MASK, + val); + return ret; } -static int rk730_dai_mute(struct snd_soc_dai *codec_dai, int mute, int direction) +static int rk730_dai_mute(struct snd_soc_dai *codec_dai, int mute, int stream) { struct snd_soc_component *component = codec_dai->component; - if (mute) - snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL, - RK730_DDAC_MUTE_MIXCTL_MUTE_MASK, - RK730_DDAC_MUTE_MIXCTL_MUTE); - else - snd_soc_component_update_bits(component, RK730_DDAC_MUTE_MIXCTL, - RK730_DDAC_MUTE_MIXCTL_MUTE_MASK, - RK730_DDAC_MUTE_MIXCTL_UNMUTE); + dev_dbg(component->dev, "%s %d stream %d\n", __func__, mute, stream); + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + if (mute) { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_DAC_MUTE_MASK, + RK730_DADC_DAC_MUTE); + } else { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_DAC_MUTE_MASK, + RK730_DADC_DAC_UNMUTE); + } + } else { + if (mute) { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_ADC_MUTE_MASK, + RK730_DADC_ADC_L_MUTE | + RK730_DADC_ADC_R_MUTE); + } else { + snd_soc_component_update_bits(component, RK730_DADC_SEL, + RK730_DADC_ADC_MUTE_MASK, + RK730_DADC_ADC_L_UNMUTE | + RK730_DADC_ADC_R_UNMUTE); + } + } return 0; } @@ -744,7 +818,6 @@ static const struct snd_soc_dai_ops rk730_dai_ops = { .set_fmt = rk730_dai_set_fmt, .hw_params = rk730_dai_hw_params, .mute_stream = rk730_dai_mute, - .no_capture_mute = 1, }; static struct snd_soc_dai_driver rk730_dai = { @@ -771,26 +844,19 @@ static int rk730_reset(struct snd_soc_component *component) struct rk730_priv *rk730 = snd_soc_component_get_drvdata(component); clk_prepare_enable(rk730->mclk); - snd_soc_component_write(component, RK730_DTOP_LPT_SRST, 0x40); udelay(10); /* WA: Initial micbias default, ADC stopped with micbias(>2.5v) */ snd_soc_component_update_bits(component, RK730_MIC_BIAS, - RK730_MIC_BIAS_VOLT_MASK, - RK730_MIC_BIAS_VOLT_2_2V); - /* PF: Use the maximum bias current for better performance */ - snd_soc_component_update_bits(component, RK730_HK_TOP_1, - RK730_HK_TOP_1_IBIAS_STD_SEL_MASK | - RK730_HK_TOP_1_IBIAS_GAIN_SEL_MASK, - RK730_HK_TOP_1_IBIAS_STD_SEL_27_5UA | - RK730_HK_TOP_1_IBIAS_GAIN_SEL_200); + RK730_MIC_BIAS_VOLT_MASK, + RK730_MIC_BIAS_VOLT_2_2V); /* PF: Use the chop 400kHz for better ADC noise performance */ snd_soc_component_update_bits(component, RK730_MIC_BOOST_3, - RK730_MIC_BOOST_3_MIC_CHOP_MASK, - RK730_MIC_BOOST_3_MIC_CHOP(RK730_CHOP_FREQ_400KHZ)); + RK730_MIC_BOOST_3_MIC_CHOP_MASK, + RK730_MIC_BOOST_3_MIC_CHOP(RK730_CHOP_FREQ_400KHZ)); snd_soc_component_update_bits(component, RK730_ADC_PGA_BLOCK_1, - RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK, - RK730_ADC_PGA_BLOCK_1_PGA_CHOP(RK730_CHOP_FREQ_400KHZ)); - + RK730_ADC_PGA_BLOCK_1_PGA_CHOP_MASK, + RK730_ADC_PGA_BLOCK_1_PGA_CHOP(RK730_CHOP_FREQ_400KHZ)); + snd_soc_component_write(component, RK730_SYSPLL_3, 0x64); clk_disable_unprepare(rk730->mclk); return 0; @@ -833,83 +899,104 @@ static const struct snd_soc_component_driver rk730_component_driver = { }; static const struct reg_default rk730_reg_defaults[] = { - { 0x00, 0x40 }, - { 0x02, 0x17 }, - { 0x05, 0x03 }, - { 0x06, 0x22 }, - { 0x07, 0x02 }, - { 0x08, 0x07 }, - { 0x09, 0x01 }, - { 0x0a, 0x01 }, - { 0x0b, 0x01 }, - { 0x0c, 0x01 }, - { 0x0d, 0x01 }, - { 0x0e, 0x01 }, - { 0x0f, 0x07 }, - { 0x10, 0x07 }, - { 0x11, 0xff }, - { 0x12, 0x07 }, - { 0x13, 0x54 }, - { 0x14, 0x04 }, - { 0x15, 0x23 }, - { 0x16, 0x35 }, - { 0x17, 0x67 }, - { 0x18, 0x1e }, - { 0x19, 0xc0 }, - { 0x1a, 0x13 }, - { 0x1b, 0x04 }, - { 0x1c, 0x20 }, - { 0x1f, 0x90 }, - { 0x20, 0x11 }, - { 0x21, 0x09 }, - { 0x22, 0x33 }, - { 0x24, 0x11 }, - { 0x25, 0x11 }, - { 0x26, 0x09 }, - { 0x27, 0x02 }, - { 0x28, 0x2c }, - { 0x2a, 0x0c }, - { 0x2b, 0x80 }, - { 0x40, 0x03 }, - { 0x42, 0x20 }, - { 0x47, 0xe6 }, - { 0x48, 0xd0 }, - { 0x49, 0x17 }, - { 0x4a, 0x26 }, - { 0x4b, 0x01 }, - { 0x4c, 0x05 }, - { 0x4d, 0x0e }, - { 0x4e, 0x09 }, - { 0x4f, 0x02 }, - { 0x5b, 0xe6 }, - { 0x5c, 0xd0 }, - { 0x5d, 0x17 }, - { 0x5e, 0x26 }, - { 0x5f, 0x01 }, - { 0x60, 0x05 }, - { 0x61, 0x0e }, - { 0x62, 0x09 }, - { 0x63, 0x20 }, - { 0x66, 0x01 }, - { 0x69, 0x17 }, - { 0x6c, 0x17 }, + {0x00, 0x08}, + {0x01, 0xc0}, + {0x02, 0x00}, + {0x03, 0x00}, + {0x04, 0x03}, + {0x05, 0x42}, + {0x06, 0x02}, + {0x07, 0x05}, + {0x08, 0x07}, + {0x09, 0x70}, + {0x0a, 0x01}, + {0x0b, 0x01}, + {0x0c, 0x01}, + {0x0d, 0x01}, + {0x0e, 0x01}, + {0x0f, 0x01}, + {0x10, 0xff}, + {0x11, 0x07}, + {0x12, 0x54}, + {0x13, 0x04}, + {0x14, 0x23}, + {0x15, 0x35}, + {0x16, 0x67}, + {0x17, 0x1e}, + {0x18, 0xc0}, + {0x19, 0x13}, + {0x1a, 0x04}, + {0x1b, 0x20}, + {0x1c, 0x00}, + {0x1d, 0x00}, + {0x1e, 0x90}, + {0x1f, 0x11}, + {0x20, 0x09}, + {0x21, 0xac}, + {0x22, 0x80}, + {0x23, 0x00}, + {0x24, 0xac}, + {0x25, 0x80}, + {0x26, 0x00}, + {0x27, 0x00}, + {0x28, 0x20}, + {0x29, 0x00}, + {0x40, 0x00}, + {0x41, 0x00}, + {0x42, 0x00}, + {0x43, 0x88}, + {0x44, 0x01}, + {0x45, 0xff}, + {0x46, 0x00}, + {0x47, 0x00}, + {0x48, 0x00}, + {0x49, 0x00}, + {0x4a, 0x00}, + {0x4b, 0x00}, + {0x4c, 0xff}, + {0x4d, 0xff}, + {0x4e, 0x1e}, + {0x4f, 0xf4}, + {0x50, 0x00}, + {0x51, 0x00}, + {0x52, 0x1f}, + {0x53, 0x1f}, + {0x54, 0x02}, + {0x55, 0x00}, + {0x56, 0xc0}, + {0x57, 0x06}, + {0x58, 0x60}, + {0x59, 0x07}, + {0x5a, 0x03}, + {0x5b, 0x00}, + {0x5c, 0x03}, + {0x5d, 0x66}, + {0x5e, 0x9a}, + {0x5f, 0xcc}, + {0x60, 0x1f}, + {0x61, 0xcc}, + {0x62, 0x0e}, + {0x63, 0x08}, + {0x64, 0x06}, + {0x65, 0x02}, + {0x66, 0x05}, + {0x67, 0x01}, + {0x68, 0x00}, + {0x69, 0x01}, + {0x6a, 0x00}, + {0x6b, 0x00}, + {0x6c, 0x00}, + {0x6d, 0x17}, + {0x6e, 0x00}, + {0x6f, 0x00}, + {0x70, 0x17}, + {0x71, 0x00}, }; -static bool rk730_volatile_register(struct device *dev, unsigned int reg) -{ - switch (reg) { - case RK730_DTOP_LPT_SRST: - return true; - default: - return false; - } -} - static const struct regmap_config rk730_regmap = { .reg_bits = 8, .val_bits = 8, - .volatile_reg = rk730_volatile_register, - .max_register = RK730_DAC_ATTN, + .max_register = RK730_DI2S_TXCR3_TXCMD, .reg_defaults = rk730_reg_defaults, .num_reg_defaults = ARRAY_SIZE(rk730_reg_defaults), .cache_type = REGCACHE_RBTREE, diff --git a/sound/soc/codecs/rk730.h b/sound/soc/codecs/rk730.h index b06f81828bb4..b9ad4857e20f 100644 --- a/sound/soc/codecs/rk730.h +++ b/sound/soc/codecs/rk730.h @@ -12,98 +12,101 @@ #define RK730_HK_TOP_0 0x00 #define RK730_HK_TOP_1 0x01 #define RK730_HK_TOP_2 0x02 -#define RK730_HK_TRIM_0 0x03 -#define RK730_HK_TRIM_1 0x04 -#define RK730_ADC_0 0x05 -#define RK730_ADC_1 0x06 -#define RK730_ADC_2 0x07 +#define RK730_HK_TRIM 0x03 +#define RK730_ADC_0 0x04 +#define RK730_ADC_1 0x05 +#define RK730_ADC_2 0x06 +#define RK730_ADC_3 0x07 #define RK730_DAC_0 0x08 #define RK730_DAC_1 0x09 -#define RK730_DAC_2 0x0a -#define RK730_MIC_BOOST_0 0x0b -#define RK730_MIC_BOOST_1 0x0c -#define RK730_MIC_BOOST_2 0x0d -#define RK730_MIC_BOOST_3 0x0e -#define RK730_ADC_PGA_BLOCK_0 0x0f -#define RK730_ADC_PGA_BLOCK_1 0x10 -#define RK730_SYSPLL_0 0x11 -#define RK730_SYSPLL_1 0x12 -#define RK730_SYSPLL_2 0x13 -#define RK730_SYSPLL_3 0x14 -#define RK730_SYSPLL_LOOP_0 0x15 -#define RK730_SYSPLL_LOOP_1 0x16 -#define RK730_SYSPLL_LOOP_2 0x17 -#define RK730_SYSPLL_LOOP_3 0x18 -#define RK730_SYSPLL_RVCO_0 0x19 -#define RK730_SYSPLL_RVCO_1 0x1a -#define RK730_SYSPLL_RVCO_2 0x1b -#define RK730_SYSPLL_RVCO_3 0x1c -#define RK730_SYSPLL_FRACT_0 0x1d -#define RK730_SYSPLL_FRACT_1 0x1e -#define RK730_SYSPLL_FRACT_2 0x1f -#define RK730_LDO 0x20 -#define RK730_MIC_BIAS 0x21 -#define RK730_MUXER_0 0x22 -#define RK730_MUXER_1 0x23 -#define RK730_MIXER_0 0x24 -#define RK730_MIXER_1 0x25 -#define RK730_MIXER_2 0x26 -#define RK730_CHARGE_PUMP 0x27 -#define RK730_HP_0 0x28 -#define RK730_HP_1 0x29 -#define RK730_LINEOUT_0 0x2a -#define RK730_LINEOUT_1 0x2b - +#define RK730_MIC_BOOST_0 0x0a +#define RK730_MIC_BOOST_1 0x0b +#define RK730_MIC_BOOST_2 0x0c +#define RK730_MIC_BOOST_3 0x0d +#define RK730_ADC_PGA_BLOCK_0 0x0e +#define RK730_ADC_PGA_BLOCK_1 0x0f +#define RK730_SYSPLL_0 0x10 +#define RK730_SYSPLL_1 0x11 +#define RK730_SYSPLL_2 0x12 +#define RK730_SYSPLL_3 0x13 +#define RK730_SYSPLL_LOOP_0 0x14 +#define RK730_SYSPLL_LOOP_1 0x15 +#define RK730_SYSPLL_LOOP_2 0x16 +#define RK730_SYSPLL_LOOP_3 0x17 +#define RK730_SYSPLL_RVCO_0 0x18 +#define RK730_SYSPLL_RVCO_1 0x19 +#define RK730_SYSPLL_RVCO_2 0x1a +#define RK730_SYSPLL_RVCO_3 0x1b +#define RK730_SYSPLL_FRACT_0 0x1c +#define RK730_SYSPLL_FRACT_1 0x1d +#define RK730_SYSPLL_FRACT_2 0x1e +#define RK730_LDO 0x1f +#define RK730_MIC_BIAS 0x20 +/* SPK->LOUT1 HP -> LOUT2*/ +#define RK730_HP_0 0x21 +#define RK730_HP_1 0x22 +#define RK730_HP_2 0x23 +#define RK730_SPK_0 0x24 +#define RK730_SPK_1 0x25 +#define RK730_REG_REDG_0 0x26 +#define RK730_REG_REDG_1 0x27 +#define RK730_REG_REDG_2 0x28 +#define RK730_TEST 0x29 /* RK730 Digital Registers Definition */ -#define RK730_DTOP_VUCTL 0x40 -#define RK730_DTOP_VUCTIME 0x41 -#define RK730_DTOP_LPT_SRST 0x42 -#define RK730_DTOP_DIGEN_CLKE 0x43 -#define RK730_DADC_VOLL 0x44 -#define RK730_DADC_VOLR 0x45 -#define RK730_DADC_SR_ACL 0x46 -#define RK730_DADC_PR_0 0x47 -#define RK730_DADC_PR_1 0x48 -#define RK730_DADC_PR_2 0x49 -#define RK730_DADC_PR_3 0x4a -#define RK730_DADC_NG_0 0x4b -#define RK730_DADC_NG_1 0x4c -#define RK730_DADC_NG_2 0x4d -#define RK730_DADC_NG_3 0x4e -#define RK730_DADC_CICCOMP 0x4f -#define RK730_DADC_HPF 0x50 -#define RK730_DADC_RVOLL 0x51 -#define RK730_DADC_RVOLR 0x52 -#define RK730_DMIC_LMT_1 0x53 -#define RK730_DMIC_LMT_2 0x54 -#define RK730_DMIC_NG_1 0x55 -#define RK730_DMIC_NG_2 0x56 -#define RK730_DDAC_POPD_DACST 0x57 -#define RK730_DDAC_VOLL 0x58 -#define RK730_DDAC_VOLR 0x59 -#define RK730_DDAC_SR_LMT 0x5a -#define RK730_DDAC_PR_0 0x5b -#define RK730_DDAC_PR_1 0x5c -#define RK730_DDAC_PR_2 0x5d -#define RK730_DDAC_PR_3 0x5e -#define RK730_DDAC_NG_0 0x5f -#define RK730_DDAC_NG_1 0x60 -#define RK730_DDAC_NG_2 0x61 -#define RK730_DDAC_NG_3 0x62 -#define RK730_DDAC_MUTE_MIXCTL 0x63 -#define RK730_DDAC_RVOLL 0x64 -#define RK730_DDAC_RVOLR 0x65 -#define RK730_DI2S_CKM 0x66 -#define RK730_DI2S_RSD 0x67 -#define RK730_DI2S_RXCR_1 0x68 -#define RK730_DI2S_RXCR_2 0x69 -#define RK730_DI2S_RXCMD_TSD 0x6a -#define RK730_DI2S_TXCR_1 0x6b -#define RK730_DI2S_TXCR_2 0x6c -#define RK730_DI2S_TXCR_3_TXCMD 0x6d -#define RK730_DAC_ATTN 0x6e +#define RK730_DTOP_DIGEN_CLKE 0x40 +#define RK730_DTOP_SRT 0x41 +#define RK730_DADC_SEL 0x42 +#define RK730_DDAC_SEL 0x43 +#define RK730_DTOP_VUCTL 0x44 +#define RK730_DTOP_VUCTIME 0x45 +#define RK730_DADC_VOLL 0x46 +#define RK730_DADC_VOLR 0x47 +#define RK730_DDAC_VOLL 0x48 +#define RK730_DDAC_VOLR 0x49 +#define RK730_DADC_RVOLL 0x4a +#define RK730_DADC_RVOLR 0x4b +#define RK730_DDAC_RVOLL 0x4c +#define RK730_DDAC_RVOLR 0x4d +#define RK730_DADC_FILTER 0x4e +#define RK730_DDAC_FILTER 0x4f +#define RK730_DDAC_PREL 0x50 +#define RK730_DDAC_PRER 0x51 +#define RK730_DDAC_POSTL 0x52 +#define RK730_DDAC_POSTR 0x53 +#define RK730_DADC_AGC0 0x54 +#define RK730_DADC_AGC1 0x55 +#define RK730_DADC_AGC2 0x56 +#define RK730_DADC_AGC3 0x57 +#define RK730_DADC_AGC4 0x58 +#define RK730_DADC_AGC5 0x59 +#define RK730_DADC_AGC6 0x5a +#define RK730_DADC_AGC7 0x5b +#define RK730_DADC_AGC8 0x5c +#define RK730_DADC_AGC9 0x5d +#define RK730_DDAC_DRC0 0x5e +#define RK730_DDAC_DRC1 0x5f +#define RK730_DDAC_DRC2 0x60 +#define RK730_DDAC_DRC3 0x61 +#define RK730_DDAC_DRC4 0x62 +#define RK730_DDAC_DRC5 0x63 +#define RK730_DDAC_DRC6 0x64 +#define RK730_DDAC_DRC7 0x65 +#define RK730_DDAC_DRC8 0x66 +#define RK730_DDAC_DRC9 0x67 +#define RK730_READ1 0x68 +#define RK730_DI2S_CKM 0x69 +#define RK730_DI2S_OFFSET 0x6a +#define RK730_DI2S_RSD 0x6b +#define RK730_DI2S_RXCR1 0x6c +#define RK730_DI2S_RXCR2 0x6d +#define RK730_DI2S_RXCMD_TSD 0x6e +#define RK730_DI2S_TXCR1 0x6f +#define RK730_DI2S_TXCR2 0x70 +#define RK730_DI2S_TXCR3_TXCMD 0x71 /* RK730_HK_TOP_1 */ +#define RK730_HK_TOP_1_HK_PWD_VAG_BUF BIT(7) +#define RK730_HK_TOP_1_HK_PWD_DAC_BUF BIT(6) #define RK730_HK_TOP_1_DAC_REF_BUF_CHOP_MASK GENMASK(7, 6) #define RK730_HK_TOP_1_DAC_REF_BUF_CHOP(x) ((x) << 6) #define RK730_HK_TOP_1_IBIAS_STD_SEL_MASK GENMASK(5, 4) @@ -123,9 +126,34 @@ #define RK730_HK_TOP_1_IBIAS_GAIN_SEL_32 7 /* RK730_ADC_0 */ -#define RK730_ADC_0_DEM_EN_MASK BIT(3) -#define RK730_ADC_0_DEM_EN BIT(3) -#define RK730_ADC_0_DEM_DIS 0 +#define RK730_ADC_INT_RESET_SIGNAL BIT(2) +#define RK730_ADCR_PWR_MASK BIT(1) +#define RK730_ADCR_PWR_UP BIT(0) +#define RK730_ADCR_PWR_DOWN BIT(1) +#define RK730_ADCL_PWR_MASK BIT(0) +#define RK730_ADCL_PWR_UP BIT(0) +#define RK730_ADCL_PWR_DOWN BIT(1) +/* RK730_DAC_0 */ +#define RK730_DAC_0_DAC_HP_IBIAS_MASK BIT(2) +#define RK730_DAC_0_DAC_HP_IBIAS_OFF BIT(2) +#define RK730_DAC_0_DAC_HP_IBIAS_ON 0 +#define RK730_DAC_0_DAC_R_HP_PWD_MASK BIT(1) +#define RK730_DAC_0_DAC_R_HP_PWD BIT(1) +#define RK730_DAC_0_DAC_R_HP_PWU 0 +#define RK730_DAC_0_DAC_L_HP_PWD_MASK BIT(0) +#define RK730_DAC_0_DAC_L_HP_PWD BIT(0) +#define RK730_DAC_0_DAC_L_HP_PWU 0 + +/* RK730_DAC_1 */ +#define RK730_DAC_1_DAC_SPK_IBIAS_MASK BIT(6) +#define RK730_DAC_1_DAC_SPK_IBIAS_OFF BIT(6) +#define RK730_DAC_1_DAC_SPK_IBIAS_ON 0 +#define RK730_DAC_1_DAC_R_SPK_PWD_MASK BIT(5) +#define RK730_DAC_1_DAC_R_SPK_PWD BIT(5) +#define RK730_DAC_1_DAC_R_SPK_PWU 0 +#define RK730_DAC_1_DAC_L_SPK_PWD_MASK BIT(4) +#define RK730_DAC_1_DAC_L_SPK_PWD BIT(4) +#define RK730_DAC_1_DAC_L_SPK_PWU 0 /* RK730_MIC_BOOST_3 */ #define RK730_MIC_BOOST_3_MIC_CHOP_MASK GENMASK(7, 6) @@ -142,6 +170,40 @@ #define RK730_MIC_BIAS_VOLT_2_2V (1 << 2) #define RK730_MIC_BIAS_VOLT_2_0V (0 << 2) +/* RK730_HP_0 */ +#define RK730_HP_0_ANTIPOP_PWR_MASK BIT(7) +#define RK730_HP_0_ANTIPOP_PWR_OFF BIT(7) +#define RK730_HP_0_ANTIPOP_PWR_ON 0 +#define RK730_HP_0_HP_IBIAS_MASK BIT(5) +#define RK730_HP_0_HP_IBIAS_OFF BIT(5) +#define RK730_HP_0_HP_IBIAS_ON 0 +#define RK730_HP_0_HP_TWOTAGE_EN_MASK BIT(4) +#define RK730_HP_0_HP_TWOTAGE_EN BIT(4) +#define RK730_HP_0_HP_TWOTAGE_DIS 0 +#define RK730_HP_0_HP_OSTG_PWR_MASK BIT(3) +#define RK730_HP_0_HP_OSTG_PWR_OFF BIT(3) +#define RK730_HP_0_HP_OSTG_PWR_ON 0 +#define RK730_HP_0_HP_BLOCK_PWR_MASK BIT(2) +#define RK730_HP_0_HP_BLOCK_PWR_OFF BIT(2) +#define RK730_HP_0_HP_BLOCK_PWR_ON 0 + +/* RK730_SPK_0 */ +#define RK730_SPK_0_ANTIPOP_PWR_MASK BIT(7) +#define RK730_SPK_0_ANTIPOP_PWR_OFF BIT(7) +#define RK730_SPK_0_ANTIPOP_PWR_ON 0 +#define RK730_SPK_0_SPK_IBIAS_MASK BIT(5) +#define RK730_SPK_0_SPK_IBIAS_OFF BIT(5) +#define RK730_SPK_0_SPK_IBIAS_ON 0 +#define RK730_SPK_0_SPK_TWOTAGE_EN_MASK BIT(4) +#define RK730_SPK_0_SPK_TWOTAGE_EN BIT(4) +#define RK730_SPK_0_SPK_TWOTAGE_DIS 0 +#define RK730_SPK_0_SPK_OSTAGE_PWR_MASK BIT(3) +#define RK730_SPK_0_SPK_OSTAGE_PWR_OFF BIT(3) +#define RK730_SPK_0_SPK_OSTAGE_PWR_ON 0 +#define RK730_SPK_0_SPK_BLOCK_PWR_MASK BIT(2) +#define RK730_SPK_0_SPK_BLOCK_PWR_OFF BIT(2) +#define RK730_SPK_0_SPK_BLOCK_PWR_ON 0 + /* RK730_MUXER_1 */ #define RK730_MUXER_1_MUX_OUT_CHOP_MASK GENMASK(1, 0) #define RK730_MUXER_1_MUX_OUT_CHOP(x) ((x) << 0) @@ -184,6 +246,19 @@ #define RK730_DTOP_DIGEN_CLKE_I2SRX_EN BIT(0) #define RK730_DTOP_DIGEN_CLKE_I2SRX_DIS 0 +/* RK730_DTOP_SRT */ +#define RK730_DTOP_DACSRT_MASK GENMASK(6, 4) +#define RK730_DTOP_DACSRT(x) ((x) << 4) +#define RK730_DTOP_ADCSRT_MASK GENMASK(2, 0) +#define RK730_DTOP_ADCSRT(x) (x) + +/* RK730_DTOP_VUCTL */ +#define RK730_DTOP_VUCTL_ADC_BYPS BIT(7) +#define RK730_DTOP_VUCTL_DAC_BYPS BIT(6) +#define RK730_DTOP_VUCTL_DAC_LV_POL BIT(3) +#define RK730_DTOP_VUCTL_DAC_RV_POL BIT(2) +#define RK730_DTOP_VUCTL_DACZDT BIT(0) + /* RK730_DADC_SR_ACL */ #define RK730_DADC_SR_ACL_VOLL_POL_MASK BIT(5) #define RK730_DADC_SR_ACL_VOLL_POS BIT(5) @@ -194,42 +269,79 @@ #define RK730_DADC_SR_ACL_SRT_MASK GENMASK(2, 0) #define RK730_DADC_SR_ACL_SRT(x) (x) -/* RK730_DDAC_SR_LMT */ -#define RK730_DDAC_SR_LMT_VOLL_POL_MASK BIT(5) -#define RK730_DDAC_SR_LMT_VOLL_POS BIT(5) -#define RK730_DDAC_SR_LMT_VOLL_NEG 0 -#define RK730_DDAC_SR_LMT_VOLR_POL_MASK BIT(4) -#define RK730_DDAC_SR_LMT_VOLR_POS BIT(4) -#define RK730_DDAC_SR_LMT_VOLR_NEG 0 -#define RK730_DDAC_SR_LMT_SRT_MASK GENMASK(2, 0) -#define RK730_DDAC_SR_LMT_SRT(x) (x) - /* RK730_DDAC_MUTE_MIXCTL */ -#define RK730_DDAC_MUTE_MIXCTL_MUTE_MASK BIT(0) -#define RK730_DDAC_MUTE_MIXCTL_MUTE BIT(0) -#define RK730_DDAC_MUTE_MIXCTL_UNMUTE 0 +#define RK730_DADC_DAC_MUTE_MASK BIT(4) +#define RK730_DADC_DAC_MUTE BIT(4) +#define RK730_DADC_DAC_UNMUTE 0 +#define RK730_DADC_ADC_MUTE_MASK GENMASK(3, 2) +#define RK730_DADC_ADC_R_MUTE_MASK BIT(3) +#define RK730_DADC_ADC_R_MUTE BIT(3) +#define RK730_DADC_ADC_R_UNMUTE 0 +#define RK730_DADC_ADC_L_MUTE_MASK BIT(2) +#define RK730_DADC_ADC_L_MUTE BIT(2) +#define RK730_DADC_ADC_L_UNMUTE 0 +#define RK730_DADC_ADC_DATESEL GENMASK(1, 0) +#define RK730_DADC_ADC_DATESEL_NORMAL ((0) << 0) +#define RK730_DADC_ADC_DATESEL_LEFT ((1) << 0) +#define RK730_DADC_ADC_DATESEL_RIGHT ((2) << 0) +#define RK730_DADC_ADC_DATESEL_SWAP ((3) << 0) /* RK730_DI2S_CKM */ #define RK730_DI2S_CKM_SCLK_DIV_MASK GENMASK(7, 4) #define RK730_DI2S_CKM_SCLK_DIV(x) ((x - 1) << 4) -#define RK730_DI2S_CKM_SCLK_EN_MASK BIT(2) -#define RK730_DI2S_CKM_SCLK_EN BIT(2) -#define RK730_DI2S_CKM_SCLK_DIS 0 -#define RK730_DI2S_CKM_SCLK_POL_MASK BIT(1) -#define RK730_DI2S_CKM_SCLK_INVERTED BIT(1) -#define RK730_DI2S_CKM_SCLK_NORMAL 0 -#define RK730_DI2S_CKM_MST_MASK BIT(0) -#define RK730_DI2S_CKM_MST_MASTER BIT(0) -#define RK730_DI2S_CKM_MST_SLAVE 0 -/* RK730_DI2S_XCR2 */ -#define RK730_DI2S_XCR2_VDW_MASK GENMASK(4, 0) -#define RK730_DI2S_XCR2_VDW(x) (x - 1) +#define RK730_DI2S_CKM_SCLK_EN_MASK BIT(3) +#define RK730_DI2S_CKM_SCLK_EN BIT(3) +#define RK730_DI2S_CKM_SCLK_DIS 0 +#define RK730_DI2S_CKM_SCLK_POL_MASK BIT(2) +#define RK730_DI2S_CKM_SCLK_INVERTED BIT(2) +#define RK730_DI2S_CKM_SCLK_NORMAL 0 +#define RK730_DI2S_CKM_MST_MASK GENMASK(1, 0) +#define RK730_DI2S_CKM_MST_MASTER ((0x03) << 0) +#define RK730_DI2S_CKM_MST_SLAVE 0 +#define RK730_DI2S_RX_CKM_MST_MASK BIT(1) +#define RK730_DI2S_RX_CKM_MST_MASTER BIT(1) +#define RK730_DI2S_RX_CKM_MST_SLAVE 0 +#define RK730_DI2S_TX_CKM_MST_MASK BIT(0) +#define RK730_DI2S_TX_CKM_MST_MASTER BIT(0) +#define RK730_DI2S_TX_CKM_MST_SLAVE 0 + + +/* RK730_DI2S_TXCR1 */ +#define RK730_DI2S_TXCR1_TFS_TX_MASK BIT(6) +#define RK730_DI2S_TXCR1_TFS_TX_I2S 0 +#define RK730_DI2S_TXCR1_TFS_TX_PCM BIT(6) +#define RK730_DI2S_TXCR1_PBM_TX_MASK GENMASK(5, 4) +#define RK730_DI2S_TXCR1_PBM_TX_NODELAY ((0x00) << 4) +#define RK730_DI2S_TXCR1_PBM_TX_DELAY1 ((0x01) << 4) +#define RK730_DI2S_TXCR1_PBM_TX_DELAY2 ((0x02) << 4) +#define RK730_DI2S_TXCR1_PBM_TX_DELAY3 ((0x03) << 4) +#define RK730_DI2S_TXCR1_IBM_TX_MASK GENMASK(3, 2) +#define RK730_DI2S_TXCR1_IBM_TX_NORMAL ((0x00) << 2) +#define RK730_DI2S_TXCR1_IBM_TX_LEFT ((0x01) << 2) +#define RK730_DI2S_TXCR1_IBM_TX_RIGHT ((0x02) << 2) +#define RK730_DI2S_TXCR1_EXRL_TX_MASK BIT(1) +#define RK730_DI2S_TXCR1_EXRL_TX_NORMAL 0 +#define RK730_DI2S_TXCR1_EXRL_SWAP BIT(1) +#define RK730_DI2S_TXCR1_ALN_MASK BIT(0) +#define RK730_DI2S_TXCR1_LSB 0 +#define RK730_DI2S_TXCR1_MSB BIT(0) + +/* RK730_DI2S_RXCR2 */ +#define RK730_DI2S_RXCR2_VDW_MASK GENMASK(4, 0) +#define RK730_DI2S_RXCR2_VDW(x) (x - 1) /* RK730_DI2S_RXCMD_TSD */ -#define RK730_DI2S_RXCMD_TSD_RXS_MASK BIT(5) -#define RK730_DI2S_RXCMD_TSD_RXS_EN BIT(5) +#define RK730_DI2S_RXCMD_TSD_RXS_MASK BIT(7) +#define RK730_DI2S_RXCMD_TSD_RXS_EN BIT(7) #define RK730_DI2S_RXCMD_TSD_RXS_DIS 0 +#define RK730_DI2S_RXCMD_TSD_RXC_MASK BIT(7) +#define RK730_DI2S_RXCMD_TSD_RXC_EN BIT(7) +#define RK730_DI2S_RXCMD_TSD_RXC_DIS 0 + +/* RK730_DI2S_TXCR2 */ +#define RK730_DI2S_TXCR2_VDW_MASK GENMASK(4, 0) +#define RK730_DI2S_TXCR2_VDW(x) (x - 1) /* RK730_DI2S_TXCR_3_TXCMD */ #define RK730_DI2S_TXCR_3_TXCMD_TXS_MASK BIT(7)