iio: adc: sc27xx: add support for PMIC sc2730
authorCixi Geng <cixi.geng1@unisoc.com>
Tue, 19 Apr 2022 14:24:58 +0000 (22:24 +0800)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Thu, 28 Apr 2022 18:22:56 +0000 (19:22 +0100)
sc2730 is the product of sc27xx series.

Co-developed-by: Yuming Zhu <yuming.zhu1@unisoc.com>
Signed-off-by: Yuming Zhu <yuming.zhu1@unisoc.com>
Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
Link: https://lore.kernel.org/r/20220419142458.884933-8-gengcixi@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/sc27xx_adc.c

index 02d6e816790913e969adee0feba3aca118bd9f5e..e9ff2d6a8a5758fae27b4a3c0e1f233b114fdd0e 100644 (file)
 #include <linux/slab.h>
 
 /* PMIC global registers definition */
+#define SC2730_MODULE_EN               0x1808
 #define SC2731_MODULE_EN               0xc08
 #define SC27XX_MODULE_ADC_EN           BIT(5)
 #define SC2721_ARM_CLK_EN              0xc0c
+#define SC2730_ARM_CLK_EN              0x180c
 #define SC2731_ARM_CLK_EN              0xc10
 #define SC27XX_CLK_ADC_EN              BIT(5)
 #define SC27XX_CLK_ADC_CLK_EN          BIT(6)
@@ -301,6 +303,80 @@ static int sc2721_adc_get_ratio(int channel, int scale)
        return SC27XX_VOLT_RATIO(1, 1);
 }
 
+static int sc2730_adc_get_ratio(int channel, int scale)
+{
+       switch (channel) {
+       case 14:
+               switch (scale) {
+               case 0:
+                       return SC27XX_VOLT_RATIO(68, 900);
+               case 1:
+                       return SC27XX_VOLT_RATIO(68, 1760);
+               case 2:
+                       return SC27XX_VOLT_RATIO(68, 2327);
+               case 3:
+                       return SC27XX_VOLT_RATIO(68, 3654);
+               default:
+                       return SC27XX_VOLT_RATIO(1, 1);
+               }
+       case 15:
+               switch (scale) {
+               case 0:
+                       return SC27XX_VOLT_RATIO(1, 3);
+               case 1:
+                       return SC27XX_VOLT_RATIO(1000, 5865);
+               case 2:
+                       return SC27XX_VOLT_RATIO(500, 3879);
+               case 3:
+                       return SC27XX_VOLT_RATIO(500, 6090);
+               default:
+                       return SC27XX_VOLT_RATIO(1, 1);
+               }
+       case 16:
+               switch (scale) {
+               case 0:
+                       return SC27XX_VOLT_RATIO(48, 100);
+               case 1:
+                       return SC27XX_VOLT_RATIO(480, 1955);
+               case 2:
+                       return SC27XX_VOLT_RATIO(480, 2586);
+               case 3:
+                       return SC27XX_VOLT_RATIO(48, 406);
+               default:
+                       return SC27XX_VOLT_RATIO(1, 1);
+               }
+       case 21:
+       case 22:
+       case 23:
+               switch (scale) {
+               case 0:
+                       return SC27XX_VOLT_RATIO(3, 8);
+               case 1:
+                       return SC27XX_VOLT_RATIO(375, 1955);
+               case 2:
+                       return SC27XX_VOLT_RATIO(375, 2586);
+               case 3:
+                       return SC27XX_VOLT_RATIO(300, 3248);
+               default:
+                       return SC27XX_VOLT_RATIO(1, 1);
+               }
+       default:
+               switch (scale) {
+               case 0:
+                       return SC27XX_VOLT_RATIO(1, 1);
+               case 1:
+                       return SC27XX_VOLT_RATIO(1000, 1955);
+               case 2:
+                       return SC27XX_VOLT_RATIO(1000, 2586);
+               case 3:
+                       return SC27XX_VOLT_RATIO(1000, 4060);
+               default:
+                       return SC27XX_VOLT_RATIO(1, 1);
+               }
+       }
+       return SC27XX_VOLT_RATIO(1, 1);
+}
+
 static int sc2731_adc_get_ratio(int channel, int scale)
 {
        switch (channel) {
@@ -357,6 +433,33 @@ static void sc2720_adc_scale_init(struct sc27xx_adc_data *data)
        }
 }
 
+static void sc2730_adc_scale_init(struct sc27xx_adc_data *data)
+{
+       int i;
+
+       for (i = 0; i < SC27XX_ADC_CHANNEL_MAX; i++) {
+               switch (i) {
+               case 5:
+               case 10:
+               case 19:
+               case 30:
+               case 31:
+                       data->channel_scale[i] = 3;
+                       break;
+               case 7:
+               case 9:
+                       data->channel_scale[i] = 2;
+                       break;
+               case 13:
+                       data->channel_scale[i] = 1;
+                       break;
+               default:
+                       data->channel_scale[i] = 0;
+                       break;
+               }
+       }
+}
+
 static void sc2731_adc_scale_init(struct sc27xx_adc_data *data)
 {
        int i;
@@ -718,6 +821,18 @@ static const struct sc27xx_adc_variant_data sc2731_data = {
        .set_volref = false,
 };
 
+static const struct sc27xx_adc_variant_data sc2730_data = {
+       .module_en = SC2730_MODULE_EN,
+       .clk_en = SC2730_ARM_CLK_EN,
+       .scale_shift = SC27XX_ADC_SCALE_SHIFT,
+       .scale_mask = SC27XX_ADC_SCALE_MASK,
+       .bscale_cal = &big_scale_graph_calib,
+       .sscale_cal = &small_scale_graph_calib,
+       .init_scale = sc2730_adc_scale_init,
+       .get_ratio = sc2730_adc_get_ratio,
+       .set_volref = false,
+};
+
 static const struct sc27xx_adc_variant_data sc2721_data = {
        .module_en = SC2731_MODULE_EN,
        .clk_en = SC2721_ARM_CLK_EN,
@@ -829,6 +944,7 @@ static int sc27xx_adc_probe(struct platform_device *pdev)
 
 static const struct of_device_id sc27xx_adc_of_match[] = {
        { .compatible = "sprd,sc2731-adc", .data = &sc2731_data},
+       { .compatible = "sprd,sc2730-adc", .data = &sc2730_data},
        { .compatible = "sprd,sc2721-adc", .data = &sc2721_data},
        { .compatible = "sprd,sc2720-adc", .data = &sc2720_data},
        { }