--- /dev/null
+/*
+ * drivers/amlogic/media/vout/vdac/vdac_config.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+#include "vdac_dev.h"
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_gxl[] = {
+ {HHI_VDAC_CNTL0, 0, 9, 1},
+ {HHI_VDAC_CNTL0, 1, 10, 1},
+ {HHI_VDAC_CNTL0, 1, 0, 1},
+ {HHI_VDAC_CNTL1, 0, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_txl[] = {
+ {HHI_VDAC_CNTL0, 1, 9, 1},
+ {HHI_VDAC_CNTL0, 1, 10, 1},
+ {HHI_VDAC_CNTL0, 1, 0, 1},
+ {HHI_VDAC_CNTL1, 1, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_txlx[] = {
+ {HHI_VDAC_CNTL0, 1, 9, 1},
+ {HHI_VDAC_CNTL0, 1, 10, 1},
+ {HHI_VDAC_CNTL0, 1, 0, 1},
+ {HHI_VDAC_CNTL0, 0, 13, 1}, /* bandgap */
+ {HHI_VDAC_CNTL1, 1, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_g12ab[] = {
+ {HHI_VDAC_CNTL0_G12A, 0, 9, 1},
+ {HHI_VDAC_CNTL0_G12A, 1, 0, 1},
+ {HHI_VDAC_CNTL1_G12A, 0, 3, 1},
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+static struct meson_vdac_ctrl_s vdac_ctrl_enable_tl1[] = {
+ {HHI_VDAC_CNTL0_G12A, 0, 9, 1},
+ {HHI_VDAC_CNTL0_G12A, 1, 0, 1},
+ {HHI_VDAC_CNTL1_G12A, 0, 3, 1},
+ {HHI_VDAC_CNTL1_G12A, 0, 7, 1}, /* bandgap */
+ {HHI_VDAC_CNTL1_G12A, 1, 6, 1}, /* bypass avout */
+ {HHI_VDAC_CNTL1_G12A, 1, 8, 1}, /* bypass avout */
+ {VDAC_REG_MAX, 0, 0, 0},
+};
+
+/* ********************************************************* */
+static struct meson_vdac_data meson_gx_l_m_vdac_data = {
+ .cpu_id = VDAC_CPU_GX_L_M,
+ .name = "meson-gx_l_m-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_gxl,
+};
+
+static struct meson_vdac_data meson_txl_vdac_data = {
+ .cpu_id = VDAC_CPU_TXL,
+ .name = "meson-txl-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_txl,
+};
+
+static struct meson_vdac_data meson_txlx_vdac_data = {
+ .cpu_id = VDAC_CPU_TXLX,
+ .name = "meson-txlx-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_txlx,
+};
+
+static struct meson_vdac_data meson_gxlx_vdac_data = {
+ .cpu_id = VDAC_CPU_GXLX,
+ .name = "meson-gxlx-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0,
+ .reg_cntl1 = HHI_VDAC_CNTL1,
+ .ctrl_table = vdac_ctrl_enable_txl,
+};
+
+static struct meson_vdac_data meson_g12ab_vdac_data = {
+ .cpu_id = VDAC_CPU_G12AB,
+ .name = "meson-g12ab-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_g12ab,
+};
+
+static struct meson_vdac_data meson_tl1_vdac_data = {
+ .cpu_id = VDAC_CPU_TL1,
+ .name = "meson-tl1-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_tl1,
+};
+
+static struct meson_vdac_data meson_sm1_vdac_data = {
+ .cpu_id = VDAC_CPU_SM1,
+ .name = "meson-sm1-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_g12ab,
+};
+
+static struct meson_vdac_data meson_tm2_vdac_data = {
+ .cpu_id = VDAC_CPU_TM2,
+ .name = "meson-tm2-vdac",
+
+ .reg_cntl0 = HHI_VDAC_CNTL0_G12A,
+ .reg_cntl1 = HHI_VDAC_CNTL1_G12A,
+ .ctrl_table = vdac_ctrl_enable_tl1,
+};
+
+const struct of_device_id meson_vdac_dt_match[] = {
+ {
+ .compatible = "amlogic, vdac-gxl",
+ .data = &meson_gx_l_m_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-gxm",
+ .data = &meson_gx_l_m_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-txl",
+ .data = &meson_txl_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-txlx",
+ .data = &meson_txlx_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-gxlx",
+ .data = &meson_gxlx_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-g12a",
+ .data = &meson_g12ab_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-g12b",
+ .data = &meson_g12ab_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-tl1",
+ .data = &meson_tl1_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-sm1",
+ .data = &meson_sm1_vdac_data,
+ }, {
+ .compatible = "amlogic, vdac-tm2",
+ .data = &meson_tm2_vdac_data,
+ },
+ {}
+};
+
+struct meson_vdac_data *aml_vdac_config_probe(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ struct meson_vdac_data *data;
+
+ match = of_match_device(meson_vdac_dt_match, &pdev->dev);
+ if (match == NULL) {
+ pr_err("%s, no matched table\n", __func__);
+ return NULL;
+ }
+ data = (struct meson_vdac_data *)match->data;
+ if (data) {
+ pr_info("%s: cpu_id:%d, name:%s\n", __func__,
+ data->cpu_id, data->name);
+ }
+
+ return data;
+}
#include <linux/amlogic/iomap.h>
#include <linux/io.h>
#include <linux/mutex.h>
+#include "vdac_dev.h"
#define AMVDAC_NAME "amvdac"
#define AMVDAC_DRIVER_NAME "amvdac"
static struct meson_vdac_data *s_vdac_data;
static struct mutex vdac_mutex;
-#define HHI_VDAC_CNTL0 0xbd
-#define HHI_VDAC_CNTL1 0xbe
-#define HHI_VDAC_CNTL0_G12A 0xbb
-#define HHI_VDAC_CNTL1_G12A 0xbc
-
-#define VDAC_MODULE_ATV_DEMOD 0x1
-#define VDAC_MODULE_DTV_DEMOD 0x2
-#define VDAC_MODULE_TVAFE 0x4
-#define VDAC_MODULE_CVBS_OUT 0x8
-#define VDAC_MODULE_AUDIO_OUT 0x10
-
-static bool vdac_init_succ_flag;
-
/* priority for module,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; cvbsout:0x8
+ * #define VDAC_MODULE_ATV_DEMOD (1 << 0)
+ * #define VDAC_MODULE_DTV_DEMOD (1 << 1)
+ * #define VDAC_MODULE_TVAFE (1 << 2)
+ * #define VDAC_MODULE_CVBS_OUT (1 << 3)
+ * #define VDAC_MODULE_AUDIO_OUT (1 << 4)
+ * #define VDAC_MODULE_AVOUT_ATV (1 << 5)
+ * #define VDAC_MODULE_AVOUT_AV (1 << 6)
*/
static unsigned int pri_flag;
-static unsigned int vdac_cntl0_bit9;
-module_param(vdac_cntl0_bit9, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl0_bit9, "vdac_cntl0_bit9");
-
-static unsigned int vdac_cntl1_bit3;
-module_param(vdac_cntl1_bit3, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl1_bit3, "vdac_cntl1_bit3");
+static unsigned int vdac_debug_print;
-static unsigned int vdac_cntl0_bit0;
-module_param(vdac_cntl0_bit0, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl0_bit0, "vdac_cntl0_bit0");
-
-static unsigned int vdac_cntl0_bit10;
-module_param(vdac_cntl0_bit10, uint, 0644);
-MODULE_PARM_DESC(vdac_cntl0_bit10, "vdac_cntl0_bit10");
-
-static inline uint32_t vdac_hiu_reg_read(uint32_t reg)
+static inline unsigned int vdac_hiu_reg_read(unsigned int reg)
{
return aml_read_hiubus(reg);
}
-static inline void vdac_hiu_reg_write(uint32_t reg, uint32_t val)
+static inline void vdac_hiu_reg_write(unsigned int reg, unsigned int val)
{
- return aml_write_hiubus(reg, val);
+ aml_write_hiubus(reg, val);
}
-static inline void vdac_hiu_reg_setb(uint32_t reg,
- const uint32_t value,
- const uint32_t start,
- const uint32_t len)
+static inline void vdac_hiu_reg_setb(unsigned int reg, unsigned int value,
+ unsigned int start, unsigned int len)
{
- aml_write_hiubus(reg, ((aml_read_hiubus(reg) &
+ vdac_hiu_reg_write(reg, ((vdac_hiu_reg_read(reg) &
~(((1L << (len)) - 1) << (start))) |
(((value) & ((1L << (len)) - 1)) << (start))));
}
-static inline uint32_t vdac_hiu_reg_getb(uint32_t reg,
- const uint32_t start,
- const uint32_t len)
+static inline unsigned int vdac_hiu_reg_getb(unsigned int reg,
+ unsigned int start, unsigned int len)
{
- uint32_t val;
+ unsigned int val;
val = ((vdac_hiu_reg_read(reg) >> (start)) & ((1L << (len)) - 1));
return val;
}
-/* adc/dac ref signal,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void ana_ref_cntl0_bit9(bool on, unsigned int module_sel)
+static inline unsigned int vdac_vcbus_reg_read(unsigned int reg)
{
- bool enable = 0;
+ return aml_read_vcbus(reg);
+}
- /*tl1:bandgap en, bc[7] default:0 opened*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1)
- return;
+static inline void vdac_vcbus_reg_write(unsigned int reg, unsigned int val)
+{
+ aml_write_vcbus(reg, val);
+}
- switch (module_sel & 0x1f) {
- case VDAC_MODULE_ATV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* cvbs in demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- case VDAC_MODULE_AUDIO_OUT: /* audio out ctrl*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- if (on)
- vdac_cntl0_bit9 |= VDAC_MODULE_AUDIO_OUT;
- else
- vdac_cntl0_bit9 &= ~VDAC_MODULE_AUDIO_OUT;
- }
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
- }
- /* pr_info("\nvdac_cntl0_bit9: 0x%x\n", vdac_cntl0_bit9); */
+static inline void vdac_vcbus_reg_setb(unsigned int reg, unsigned int value,
+ unsigned int start, unsigned int len)
+{
+ vdac_vcbus_reg_write(reg, ((vdac_vcbus_reg_read(reg) &
+ ~(((1L << (len)) - 1) << (start))) |
+ (((value) & ((1L << (len)) - 1)) << (start))));
+}
- if ((vdac_cntl0_bit9 & 0x1f) == 0)
- enable = 0;
- else
- enable = 1;
+static inline unsigned int vdac_vcbus_reg_getb(unsigned int reg,
+ unsigned int start, unsigned int len)
+{
+ unsigned int val;
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, enable, 9, 1);
- else if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0_G12A, ~enable, 9, 1);
- else
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, ~enable, 9, 1);
+ val = ((vdac_vcbus_reg_read(reg) >> (start)) & ((1L << (len)) - 1));
+
+ return val;
}
-EXPORT_SYMBOL(ana_ref_cntl0_bit9);
-/*avin cvbsout signal,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void vdac_out_cntl0_bit10(bool on, unsigned int module_sel)
+static int vdac_ctrl_config(bool on, unsigned int reg, unsigned int bit)
{
- bool enable = 0;
-
- /*bit10 is for bandgap startup setting in g12a*/
- if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- return;
+ struct meson_vdac_ctrl_s *table = s_vdac_data->ctrl_table;
+ unsigned int val;
+ int i = 0;
+ int ret = -1;
- switch (module_sel & 0xf) {
- case VDAC_MODULE_ATV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* av in demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs out demod */
- if (on)
- vdac_cntl0_bit10 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl0_bit10 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
+ while (i < VDAC_CTRL_MAX) {
+ if (table[i].reg == VDAC_REG_MAX)
+ break;
+ if ((table[i].reg == reg) && (table[i].bit == bit)) {
+ if (on)
+ val = table[i].val;
+ else
+ val = table[i].val ? 0 : 1;
+ vdac_hiu_reg_setb(reg, val, bit, table[i].len);
+ if (vdac_debug_print) {
+ pr_info("vdac: reg=0x%02x set bit%d=%d, readback=0x%08x\n",
+ reg, bit, val, vdac_hiu_reg_read(reg));
+ }
+ ret = 0;
+ break;
+ }
+ i++;
}
- /* pr_info("\vdac_cntl0_bit0: 0x%x\n", vdac_cntl1_bit3); */
- if ((vdac_cntl0_bit10 & 0xf) == 0)
- enable = 0;
- else
- enable = 1;
-
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, enable, 10, 1);
+ return ret;
}
-EXPORT_SYMBOL(vdac_out_cntl0_bit10);
-/*atv cvbsout signal,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void vdac_out_cntl0_bit0(bool on, unsigned int module_sel)
+static void vdac_enable_avout_atv(bool on)
{
- bool enable = 0;
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ /* clock delay control */
+ vdac_hiu_reg_setb(HHI_VIID_CLK_DIV, 1, 19, 1);
+ /* vdac_clock_mux form atv demod */
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 1, 8, 1);
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 1, 4, 1);
+ /* vdac_clk gated clock control */
+ vdac_vcbus_reg_setb(VENC_VDAC_DACSEL0, 1, 5, 1);
+
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ /*after txlx need reset bandgap after bit9 enabled*/
+ /*bit10 reset bandgap in g12a*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
- switch (module_sel & 0xf) {
- case VDAC_MODULE_ATV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* av in demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
- if (on)
- vdac_cntl0_bit0 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl0_bit0 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
- }
- /* pr_info("\vdac_cntl0_bit0: 0x%x\n", vdac_cntl1_bit3); */
+ /*Cdac pwd*/
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ /* enable AFE output buffer */
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ vdac_ctrl_config(1, reg_cntl0, 0);
- if ((vdac_cntl0_bit0 & 0xf) == 0)
- enable = 0;
- else
- enable = 1;
- if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0_G12A, enable, 0, 1);
- else
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, enable, 0, 1);
+ } else {
+ vdac_ctrl_config(0, reg_cntl0, 9);
+
+ vdac_ctrl_config(0, reg_cntl0, 0);
+ /* Disable AFE output buffer */
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ /* disable dac output */
+ vdac_ctrl_config(0, reg_cntl1, 3);
+
+ /* vdac_clk gated clock control */
+ vdac_vcbus_reg_setb(VENC_VDAC_DACSEL0, 0, 5, 1);
+ /* vdac_clock_mux form atv demod */
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 0, 4, 1);
+ vdac_hiu_reg_setb(HHI_VID_CLK_CNTL2, 0, 8, 1);
+ /* clock delay control */
+ vdac_hiu_reg_setb(HHI_VIID_CLK_DIV, 0, 19, 1);
+ }
}
-EXPORT_SYMBOL(vdac_out_cntl0_bit0);
-/* dac out pwd ctl,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
-void vdac_out_cntl1_bit3(bool on, unsigned int module_sel)
+static void vdac_enable_dtv_demod(bool on)
{
- bool enable = 0;
-
- switch (module_sel & 0xf) {
- case VDAC_MODULE_ATV_DEMOD: /* atv demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_ATV_DEMOD;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_ATV_DEMOD;
- break;
- case VDAC_MODULE_DTV_DEMOD: /* dtv demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_DTV_DEMOD;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_DTV_DEMOD;
- break;
- case VDAC_MODULE_TVAFE: /* av in demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_TVAFE;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_TVAFE;
- break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
- if (on)
- vdac_cntl1_bit3 |= VDAC_MODULE_CVBS_OUT;
- else
- vdac_cntl1_bit3 &= ~VDAC_MODULE_CVBS_OUT;
- break;
- default:
- pr_err("module_sel: 0x%x wrong module index !! ", module_sel);
- break;
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ vdac_ctrl_config(1, reg_cntl0, 0);
+ } else {
+ vdac_ctrl_config(0, reg_cntl0, 9);
+ vdac_ctrl_config(0, reg_cntl1, 3);
}
- /* pr_info("\nvdac_cntl1_bit3: 0x%x\n", vdac_cntl1_bit3); */
+}
- if ((vdac_cntl1_bit3 & 0xf) == 0)
- enable = 0;
- else
- enable = 1;
+static void vdac_enable_avout_av(bool on)
+{
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ /*txlx need reset bandgap after bit9 enabled*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1, enable, 3, 1);
- else if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, ~enable, 3, 1);
- else
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1, ~enable, 3, 1);
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(1, reg_cntl0, 10);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ /*[6][8]bypass buffer enable*/
+ vdac_ctrl_config(1, reg_cntl1, 6);
+ vdac_ctrl_config(1, reg_cntl1, 8);
+ }
+ } else {
+ vdac_ctrl_config(0, reg_cntl0, 9);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ /*[6][8]bypass buffer disable*/
+ vdac_ctrl_config(0, reg_cntl1, 6);
+ vdac_ctrl_config(0, reg_cntl1, 8);
+ }
+
+ /* Disable AFE output buffer */
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
+ /* disable dac output */
+ vdac_ctrl_config(0, reg_cntl1, 3);
+ }
}
-EXPORT_SYMBOL(vdac_out_cntl1_bit3);
-void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1)
+static void vdac_enable_cvbs_out(bool on)
{
- if (!s_vdac_data) {
- pr_err("\n%s: s_vdac_data NULL\n", __func__);
- return;
- }
- if (s_vdac_data->cpu_id >= VDAC_CPU_G12AB) {
- vdac_hiu_reg_write(HHI_VDAC_CNTL0_G12A, ctrl0);
- vdac_hiu_reg_write(HHI_VDAC_CNTL1_G12A, ctrl1);
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+ unsigned int reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ if (on) {
+ vdac_ctrl_config(1, reg_cntl1, 3);
+ vdac_ctrl_config(1, reg_cntl0, 0);
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
+ vdac_ctrl_config(0, reg_cntl0, 13);
+ udelay(5);
+ vdac_ctrl_config(1, reg_cntl0, 13);
+ }
+ if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
+ vdac_ctrl_config(0, reg_cntl0, 10);
} else {
- vdac_hiu_reg_write(HHI_VDAC_CNTL0, ctrl0);
- vdac_hiu_reg_write(HHI_VDAC_CNTL1, ctrl1);
+ vdac_ctrl_config(0, reg_cntl0, 9);
+ vdac_ctrl_config(0, reg_cntl0, 0);
+ vdac_ctrl_config(0, reg_cntl1, 3);
+ }
+}
+
+static void vdac_enable_audio_out(bool on)
+{
+ unsigned int reg_cntl0 = s_vdac_data->reg_cntl0;
+
+ /*Bandgap optimization*/
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXLX)
+ vdac_hiu_reg_setb(reg_cntl0, 0xe, 3, 5);
+
+ if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
+ s_vdac_data->cpu_id == VDAC_CPU_TXLX ||
+ s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ if (on)
+ vdac_ctrl_config(1, reg_cntl0, 9);
+ else
+ vdac_ctrl_config(0, reg_cntl0, 9);
}
}
-EXPORT_SYMBOL(vdac_set_ctrl0_ctrl1);
-/* dac ctl,
- * module index: atv demod:0x01; dtv demod:0x02; tvafe:0x4; dac:0x8
- */
void vdac_enable(bool on, unsigned int module_sel)
{
if (!s_vdac_data) {
return;
}
- pr_info("\n%s: on:%d,module_sel:%x\n", __func__, on, module_sel);
+ pr_info("\n%s: %d, module_sel:0x%x, private_flag:0x%x\n",
+ __func__, on, module_sel, pri_flag);
mutex_lock(&vdac_mutex);
switch (module_sel) {
- case VDAC_MODULE_ATV_DEMOD: /* atv demod */
- if ((on && (pri_flag & VDAC_MODULE_ATV_DEMOD))
- || (!on && !(pri_flag & VDAC_MODULE_ATV_DEMOD))) {
- pr_info("%s: ATV DEMOD had done!:%d.\n", __func__, on);
- break;
- }
-
+ case VDAC_MODULE_AVOUT_ATV: /* atv avout */
if (on) {
- ana_ref_cntl0_bit9(1, VDAC_MODULE_ATV_DEMOD);
- /*after txlx need reset bandgap after bit9 enabled*/
- /*bit10 reset bandgap in g12a*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
+ if (pri_flag & VDAC_MODULE_AVOUT_ATV) {
+ pr_info("%s: avout_atv is already on\n",
+ __func__);
+ break;
}
- pri_flag &= ~VDAC_MODULE_TVAFE;
- pri_flag |= VDAC_MODULE_ATV_DEMOD;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ pri_flag |= VDAC_MODULE_AVOUT_ATV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
break;
- /*Cdac pwd*/
- vdac_out_cntl1_bit3(1, VDAC_MODULE_ATV_DEMOD);
- /* enable AFE output buffer */
- if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 10, 1);
- vdac_out_cntl0_bit0(1, VDAC_MODULE_ATV_DEMOD);
+ }
+ vdac_enable_avout_atv(1);
} else {
- ana_ref_cntl0_bit9(0, VDAC_MODULE_ATV_DEMOD);
- pri_flag &= ~VDAC_MODULE_ATV_DEMOD;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ if (!(pri_flag & VDAC_MODULE_AVOUT_ATV)) {
+ pr_info("%s: avout_atv is already off\n",
+ __func__);
+ break;
+ }
+ pri_flag &= ~VDAC_MODULE_AVOUT_ATV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ if (vdac_debug_print) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
+ }
break;
- vdac_out_cntl0_bit0(0, VDAC_MODULE_ATV_DEMOD);
- /* Disable AFE output buffer */
- if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 10, 1);
- /* enable dac output */
- vdac_out_cntl1_bit3(0, VDAC_MODULE_ATV_DEMOD);
+ }
+ vdac_enable_avout_atv(0);
}
break;
case VDAC_MODULE_DTV_DEMOD: /* dtv demod */
if (on) {
- if (s_vdac_data->cpu_id == VDAC_CPU_GXLX)
- vdac_out_cntl1_bit3(1, VDAC_MODULE_DTV_DEMOD);
- ana_ref_cntl0_bit9(1, VDAC_MODULE_DTV_DEMOD);
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
- }
pri_flag |= VDAC_MODULE_DTV_DEMOD;
+ vdac_enable_dtv_demod(1);
} else {
- ana_ref_cntl0_bit9(0, VDAC_MODULE_DTV_DEMOD);
- if (s_vdac_data->cpu_id == VDAC_CPU_GXLX)
- vdac_out_cntl1_bit3(0, VDAC_MODULE_DTV_DEMOD);
pri_flag &= ~VDAC_MODULE_DTV_DEMOD;
+ if (pri_flag & VDAC_MODULE_MASK)
+ break;
+ vdac_enable_dtv_demod(0);
}
break;
- case VDAC_MODULE_TVAFE: /* av in demod */
+ case VDAC_MODULE_AVOUT_AV: /* avin avout */
if (on) {
- ana_ref_cntl0_bit9(1, VDAC_MODULE_TVAFE);
- /*after txlx need reset bandgap after bit9 enabled*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
- }
- pri_flag &= ~VDAC_MODULE_ATV_DEMOD;
- pri_flag |= VDAC_MODULE_TVAFE;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ pri_flag |= VDAC_MODULE_AVOUT_AV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
break;
- vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
- vdac_out_cntl0_bit10(1, VDAC_MODULE_TVAFE);
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
- s_vdac_data->cpu_id == VDAC_CPU_TM2) {
- /*[6][8]bypass buffer enable*/
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 6, 1);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 8, 1);
}
+ vdac_enable_avout_av(1);
} else {
- ana_ref_cntl0_bit9(0, VDAC_MODULE_TVAFE);
- if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
- s_vdac_data->cpu_id == VDAC_CPU_TM2) {
- /*[6][8]bypass buffer disable*/
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 6, 1);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 8, 1);
+ pri_flag &= ~VDAC_MODULE_AVOUT_AV;
+ if (pri_flag & VDAC_MODULE_CVBS_OUT) {
+ if (vdac_debug_print) {
+ pr_info("%s: %d, bypass for cvbsout\n",
+ __func__, on);
+ }
+ break;
}
- pri_flag &= ~VDAC_MODULE_TVAFE;
- if (pri_flag & VDAC_MODULE_CVBS_OUT)
+ if (pri_flag & VDAC_MODULE_MASK)
break;
- /* Disable AFE output buffer */
- vdac_out_cntl0_bit10(0, VDAC_MODULE_TVAFE);
- /* enable dac output */
- vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
+ vdac_enable_avout_av(0);
}
break;
- case VDAC_MODULE_CVBS_OUT: /* cvbs in demod */
+ case VDAC_MODULE_CVBS_OUT:
if (on) {
- vdac_out_cntl1_bit3(1, VDAC_MODULE_CVBS_OUT);
- vdac_out_cntl0_bit0(1, VDAC_MODULE_CVBS_OUT);
- ana_ref_cntl0_bit9(1, VDAC_MODULE_CVBS_OUT);
- if (s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 1, 13, 1);
- udelay(5);
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0, 13, 1);
- }
- vdac_out_cntl0_bit10(0, VDAC_MODULE_CVBS_OUT);
pri_flag |= VDAC_MODULE_CVBS_OUT;
+ vdac_enable_cvbs_out(1);
} else {
- /*vdac_out_cntl0_bit10(0, VDAC_MODULE_CVBS_OUT);*/
- ana_ref_cntl0_bit9(0, VDAC_MODULE_CVBS_OUT);
- vdac_out_cntl0_bit0(0, VDAC_MODULE_CVBS_OUT);
- vdac_out_cntl1_bit3(0, VDAC_MODULE_CVBS_OUT);
pri_flag &= ~VDAC_MODULE_CVBS_OUT;
- if (pri_flag & VDAC_MODULE_ATV_DEMOD) {
- vdac_out_cntl1_bit3(1, VDAC_MODULE_ATV_DEMOD);
- if (s_vdac_data->cpu_id < VDAC_CPU_G12AB)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0,
- 0, 10, 1);
- vdac_out_cntl0_bit0(1, VDAC_MODULE_ATV_DEMOD);
- } else if (pri_flag & VDAC_MODULE_TVAFE) {
- vdac_out_cntl1_bit3(0, VDAC_MODULE_TVAFE);
- vdac_out_cntl0_bit10(1, VDAC_MODULE_TVAFE);
- } else if (pri_flag & VDAC_MODULE_DTV_DEMOD) {
- if (s_vdac_data->cpu_id == VDAC_CPU_GXLX)
- vdac_out_cntl1_bit3(1,
- VDAC_MODULE_DTV_DEMOD);
- ana_ref_cntl0_bit9(1, VDAC_MODULE_DTV_DEMOD);
+ if ((pri_flag & VDAC_MODULE_MASK) == 0) {
+ vdac_enable_cvbs_out(0);
+ break;
}
+
+ if (pri_flag & VDAC_MODULE_AVOUT_ATV)
+ vdac_enable_avout_atv(1);
+ else if (pri_flag & VDAC_MODULE_AVOUT_AV)
+ vdac_enable_avout_av(1);
+ else if (pri_flag & VDAC_MODULE_DTV_DEMOD)
+ vdac_enable_dtv_demod(1);
}
break;
case VDAC_MODULE_AUDIO_OUT: /* audio demod */
- /*Bandgap optimization*/
- if (s_vdac_data->cpu_id == VDAC_CPU_TXHD ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL0, 0xe, 3, 5);
-
- if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
- s_vdac_data->cpu_id == VDAC_CPU_TXLX) {
- if (on)
- ana_ref_cntl0_bit9(1, VDAC_MODULE_AUDIO_OUT);
- else
- ana_ref_cntl0_bit9(0, VDAC_MODULE_AUDIO_OUT);
+ if (on) {
+ pri_flag |= VDAC_MODULE_AUDIO_OUT;
+ vdac_enable_audio_out(1);
+ } else {
+ pri_flag &= ~VDAC_MODULE_AUDIO_OUT;
+ if (pri_flag & VDAC_MODULE_MASK)
+ break;
+ vdac_enable_audio_out(0);
}
break;
default:
break;
}
+ if (vdac_debug_print) {
+ pr_info("private_flag: 0x%02x\n"
+ "reg_cntl0: 0x%02x=0x%08x\n"
+ "reg_cntl1: 0x%02x=0x%08x\n",
+ pri_flag,
+ s_vdac_data->reg_cntl0,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl0),
+ s_vdac_data->reg_cntl1,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl1));
+ }
+
mutex_unlock(&vdac_mutex);
}
EXPORT_SYMBOL(vdac_enable);
+void vdac_set_ctrl0_ctrl1(unsigned int ctrl0, unsigned int ctrl1)
+{
+ unsigned int reg_cntl0;
+ unsigned int reg_cntl1;
+
+ if (!s_vdac_data) {
+ pr_err("\n%s: s_vdac_data NULL\n", __func__);
+ return;
+ }
+
+ reg_cntl0 = s_vdac_data->reg_cntl0;
+ reg_cntl1 = s_vdac_data->reg_cntl1;
+
+ vdac_hiu_reg_write(reg_cntl0, ctrl0);
+ vdac_hiu_reg_write(reg_cntl1, ctrl1);
+ if (vdac_debug_print) {
+ pr_info("vdac: set reg 0x%02x=0x%08x, readback=0x%08x\n",
+ reg_cntl0, ctrl0, vdac_hiu_reg_read(reg_cntl0));
+ pr_info("vdac: set reg 0x%02x=0x%08x, readback=0x%08x\n",
+ reg_cntl1, ctrl1, vdac_hiu_reg_read(reg_cntl1));
+ }
+}
+
int vdac_enable_check_dtv(void)
{
- return (pri_flag & VDAC_MODULE_DTV_DEMOD) ? 1:0;
+ return (pri_flag & VDAC_MODULE_DTV_DEMOD) ? 1 : 0;
}
-static int amvdac_open(struct inode *inode, struct file *file)
+int vdac_enable_check_cvbs(void)
{
- struct amvdac_dev_s *devp;
- /* Get the per-device structure that contains this cdev */
- devp = container_of(inode->i_cdev, struct amvdac_dev_s, cdev);
- file->private_data = devp;
- return 0;
+ return (pri_flag & VDAC_MODULE_CVBS_OUT) ? 1 : 0;
}
-static int amvdac_release(struct inode *inode, struct file *file)
+/* ********************************************************* */
+static ssize_t vdac_info_show(struct class *class,
+ struct class_attribute *attr, char *buf)
{
- file->private_data = NULL;
- return 0;
+ ssize_t len = 0;
+
+ if (!s_vdac_data)
+ return sprintf(buf, "vdac data is NULL\n");
+
+ len = sprintf(buf, "vdac driver info:\n");
+ len += sprintf(buf + len,
+ "chip_type: %s(%d)\n"
+ "private_flag: 0x%02x\n"
+ "reg_cntl0: 0x%02x=0x%08x\n"
+ "reg_cntl1: 0x%02x=0x%08x\n"
+ "debug_print: %d\n",
+ s_vdac_data->name, s_vdac_data->cpu_id, pri_flag,
+ s_vdac_data->reg_cntl0,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl0),
+ s_vdac_data->reg_cntl1,
+ vdac_hiu_reg_read(s_vdac_data->reg_cntl1),
+ vdac_debug_print);
+
+ return len;
}
-static const struct file_operations amvdac_fops = {
- .owner = THIS_MODULE,
- .open = amvdac_open,
- .release = amvdac_release,
+static const char *vdac_debug_usage_str = {
+"Usage:\n"
+" cat /sys/class/amvdac/info ; print vdac information\n"
+" echo flag > /sys/class/amvdac/debug ; vdac_private_flag config\n"
+" echo print <val_dec> > /sys/class/amvdac/debug ; vdac_debug_print config\n"
};
-struct meson_vdac_data meson_gxtvbb_vdac_data = {
- .cpu_id = VDAC_CPU_GXTVBB,
- .name = "meson-gxtvbb-vdac",
-};
+static ssize_t vdac_debug_show(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", vdac_debug_usage_str);
+}
-struct meson_vdac_data meson_gx_l_m_vdac_data = {
- .cpu_id = VDAC_CPU_GX_L_M,
- .name = "meson-gx_l_m-vdac",
-};
+static void vdac_parse_param(char *buf_orig, char **parm)
+{
+ char *ps, *token;
+ char delim1[3] = " ";
+ char delim2[2] = "\n";
+ unsigned int n = 0;
+
+ ps = buf_orig;
+ strcat(delim1, delim2);
+ while (1) {
+ token = strsep(&ps, delim1);
+ if (token == NULL)
+ break;
+ if (*token == '\0')
+ continue;
+ parm[n++] = token;
+ }
+}
-struct meson_vdac_data meson_txl_vdac_data = {
- .cpu_id = VDAC_CPU_TXL,
- .name = "meson-txl-vdac",
-};
+static ssize_t vdac_debug_store(struct class *class,
+ struct class_attribute *attr, const char *buff, size_t count)
+{
+ char *buf_orig;
+ char *parm[3] = {NULL};
-struct meson_vdac_data meson_txlx_vdac_data = {
- .cpu_id = VDAC_CPU_TXLX,
- .name = "meson-txlx-vdac",
-};
+ if (!s_vdac_data) {
+ pr_info("vdac data is null\n");
+ return count;
+ }
-struct meson_vdac_data meson_gxlx_vdac_data = {
- .cpu_id = VDAC_CPU_GXLX,
- .name = "meson-gxlx-vdac",
-};
+ buf_orig = kstrdup(buff, GFP_KERNEL);
+ vdac_parse_param(buf_orig, (char **)&parm);
+ if (parm[0] == NULL)
+ return count;
+
+ if (!strcmp(parm[0], "flag")) {
+ pr_info("vdac_private_flag: 0x%x\n", pri_flag);
+ } else if (!strcmp(parm[0], "print")) {
+ if (parm[1]) {
+ if (kstrtouint(parm[1], 10, &vdac_debug_print) < 0)
+ goto vdac_store_err;
+ }
+ pr_info("vdac_debug_print:%d\n", vdac_debug_print);
+ } else {
+ pr_info("invalid cmd\n");
+ }
-struct meson_vdac_data meson_txhd_vdac_data = {
- .cpu_id = VDAC_CPU_TXHD,
- .name = "meson-txhd-vdac",
-};
+ kfree(buf_orig);
+ return count;
-struct meson_vdac_data meson_g12ab_vdac_data = {
- .cpu_id = VDAC_CPU_G12AB,
- .name = "meson-g12ab-vdac",
-};
+vdac_store_err:
+ kfree(buf_orig);
+ return -EINVAL;
+}
-struct meson_vdac_data meson_tl1_vdac_data = {
- .cpu_id = VDAC_CPU_TL1,
- .name = "meson-tl1-vdac",
+static struct class_attribute vdac_class_attrs[] = {
+ __ATTR(info, 0644, vdac_info_show, NULL),
+ __ATTR(debug, 0644, vdac_debug_show, vdac_debug_store),
};
-struct meson_vdac_data meson_sm1_vdac_data = {
- .cpu_id = VDAC_CPU_SM1,
- .name = "meson-sm1-vdac",
-};
+static int vdac_create_class(struct amvdac_dev_s *devp)
+{
+ int i;
-struct meson_vdac_data meson_tm2_vdac_data = {
- .cpu_id = VDAC_CPU_TM2,
- .name = "meson-tm2-vdac",
-};
+ if (IS_ERR_OR_NULL(devp->clsp)) {
+ pr_err("vdac: %s debug class is null\n", __func__);
+ return -1;
+ }
-static const struct of_device_id meson_vdac_dt_match[] = {
- {
- .compatible = "amlogic, vdac-gxtvbb",
- .data = &meson_gxtvbb_vdac_data,
- }, {
- .compatible = "amlogic, vdac-gxl",
- .data = &meson_gx_l_m_vdac_data,
- }, {
- .compatible = "amlogic, vdac-gxm",
- .data = &meson_gx_l_m_vdac_data,
- }, {
- .compatible = "amlogic, vdac-txl",
- .data = &meson_txl_vdac_data,
- }, {
- .compatible = "amlogic, vdac-txlx",
- .data = &meson_txlx_vdac_data,
- }, {
- .compatible = "amlogic, vdac-gxlx",
- .data = &meson_gxlx_vdac_data,
- }, {
- .compatible = "amlogic, vdac-txhd",
- .data = &meson_txhd_vdac_data,
- }, {
- .compatible = "amlogic, vdac-g12a",
- .data = &meson_g12ab_vdac_data,
- }, {
- .compatible = "amlogic, vdac-g12b",
- .data = &meson_g12ab_vdac_data,
- }, {
- .compatible = "amlogic, vdac-tl1",
- .data = &meson_tl1_vdac_data,
- }, {
- .compatible = "amlogic, vdac-sm1",
- .data = &meson_sm1_vdac_data,
- }, {
- .compatible = "amlogic, vdac-tm2",
- .data = &meson_tm2_vdac_data,
- },
- {},
+ for (i = 0; i < ARRAY_SIZE(vdac_class_attrs); i++) {
+ if (class_create_file(devp->clsp, &vdac_class_attrs[i])) {
+ pr_err("vdac: create debug attribute %s failed\n",
+ vdac_class_attrs[i].attr.name);
+ }
+ }
+
+ return 0;
+}
+
+static int vdac_remove_class(struct amvdac_dev_s *devp)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(vdac_class_attrs); i++)
+ class_remove_file(devp->clsp, &vdac_class_attrs[i]);
+
+ class_destroy(devp->clsp);
+ devp->clsp = NULL;
+
+ return 0;
+}
+/* ********************************************************* */
+
+static int amvdac_open(struct inode *inode, struct file *file)
+{
+ struct amvdac_dev_s *devp;
+ /* Get the per-device structure that contains this cdev */
+ devp = container_of(inode->i_cdev, struct amvdac_dev_s, cdev);
+ file->private_data = devp;
+ return 0;
+}
+
+static int amvdac_release(struct inode *inode, struct file *file)
+{
+ file->private_data = NULL;
+ return 0;
+}
+
+static const struct file_operations amvdac_fops = {
+ .owner = THIS_MODULE,
+ .open = amvdac_open,
+ .release = amvdac_release,
};
+/* ********************************************************* */
static int aml_vdac_probe(struct platform_device *pdev)
{
int ret = 0;
- const struct of_device_id *match;
struct amvdac_dev_s *devp = &amvdac_dev;
memset(devp, 0, (sizeof(struct amvdac_dev_s)));
- match = of_match_device(meson_vdac_dt_match, &pdev->dev);
- if (match == NULL) {
- pr_err("%s,no matched table\n", __func__);
- return -1;
+ s_vdac_data = aml_vdac_config_probe(pdev);
+ if (!s_vdac_data) {
+ pr_err("%s: config probe failed\n", __func__);
+ return ret;
}
- s_vdac_data = (struct meson_vdac_data *)match->data;
- pr_info("%s:probe start.cpu_id:%d,name:%s\n", __func__,
- s_vdac_data->cpu_id, s_vdac_data->name);
+
+ mutex_init(&vdac_mutex);
ret = alloc_chrdev_region(&devp->devno, 0, 1, AMVDAC_NAME);
if (ret < 0)
goto fail_create_device;
}
+ vdac_create_class(devp);
+
pr_info("%s: ok\n", __func__);
return ret;
{
struct amvdac_dev_s *devp = &amvdac_dev;
+ vdac_remove_class(devp);
device_destroy(devp->clsp, devp->devno);
cdev_del(&devp->cdev);
class_destroy(devp->clsp);
unregister_chrdev_region(devp->devno, 1);
+ mutex_destroy(&vdac_mutex);
+
pr_info("%s: amvdac_exit.\n", __func__);
return 0;
{
if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
s_vdac_data->cpu_id == VDAC_CPU_TXLX)
- vdac_hiu_reg_write(HHI_VDAC_CNTL0, 0);
+ vdac_hiu_reg_write(s_vdac_data->reg_cntl0, 0);
else if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
s_vdac_data->cpu_id == VDAC_CPU_TM2)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 1, 7, 1);
+ vdac_ctrl_config(0, s_vdac_data->reg_cntl1, 7);
pr_info("%s: suspend module\n", __func__);
return 0;
}
{
/*0xbc[7] for bandgap enable: 0:enable,1:disable*/
if (s_vdac_data->cpu_id == VDAC_CPU_TL1 ||
- s_vdac_data->cpu_id == VDAC_CPU_TM2)
- vdac_hiu_reg_setb(HHI_VDAC_CNTL1_G12A, 0, 7, 1);
+ s_vdac_data->cpu_id == VDAC_CPU_TM2) {
+ vdac_ctrl_config(1, s_vdac_data->reg_cntl1, 7);
+ }
pr_info("%s: resume module\n", __func__);
return 0;
}
{
unsigned int cntl0, cntl1;
- pr_info("%s: shutdown module\n", __func__);
+ pr_info("%s: shutdown module, private_flag:0x%x\n",
+ __func__, pri_flag);
cntl0 = 0x0;
if (s_vdac_data->cpu_id == VDAC_CPU_TXL ||
s_vdac_data->cpu_id == VDAC_CPU_TXLX)
.suspend = amvdac_drv_suspend,
.resume = amvdac_drv_resume,
#endif
- .shutdown = amvdac_drv_shutdown,
+ .shutdown = amvdac_drv_shutdown,
};
static int __init aml_vdac_init(void)
{
- pr_info("%s: module init\n", __func__);
-
- vdac_init_succ_flag = 0;
s_vdac_data = NULL;
- mutex_init(&vdac_mutex);
-
if (platform_driver_register(&aml_vdac_driver)) {
pr_err("%s: failed to register vdac driver module\n", __func__);
return -ENODEV;
}
- vdac_init_succ_flag = 1;
return 0;
}
static void __exit aml_vdac_exit(void)
{
- mutex_destroy(&vdac_mutex);
- pr_info("%s: module exit\n", __func__);
platform_driver_unregister(&aml_vdac_driver);
}