diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index a89dcb6fb..dbe41fdf2 100644 --- a/drivers/iio/adc/sun4i-gpadc-iio.c +++ b/drivers/iio/adc/sun4i-gpadc-iio.c @@ -56,6 +56,7 @@ struct sun4i_gpadc_iio; struct gpadc_data { int temp_offset; int temp_scale; + int temp_divider; unsigned int tp_mode_en; unsigned int tp_adc_select; unsigned int (*adc_chan_select)(unsigned int chan); @@ -63,6 +64,7 @@ struct gpadc_data { unsigned int temp_data; int (*sample_start)(struct sun4i_gpadc_iio *info); int (*sample_end)(struct sun4i_gpadc_iio *info); + void (*reg_to_temp)(int val, int *temp); bool has_bus_clk; bool has_bus_rst; bool has_mod_clk; @@ -289,6 +291,15 @@ static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val) return 0; } +static int sun4i_gpadc_temp_divider(struct iio_dev *indio_dev, int *val) +{ + struct sun4i_gpadc_iio *info = iio_priv(indio_dev); + + *val = info->data->temp_divider; + + return 0; +} + static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -436,19 +447,32 @@ static int sun4i_gpadc_runtime_resume(struct device *dev) static int sun4i_gpadc_get_temp(void *data, int *temp) { struct sun4i_gpadc_iio *info = data; - int val, scale, offset; + int val, scale, offset, divider; if (sun4i_gpadc_temp_read(info->indio_dev, &val)) return -ETIMEDOUT; sun4i_gpadc_temp_scale(info->indio_dev, &scale); sun4i_gpadc_temp_offset(info->indio_dev, &offset); + sun4i_gpadc_temp_divider(info->indio_dev, ÷r); - *temp = (val + offset) * scale; + if (info->data->reg_to_temp) + info->data->reg_to_temp(val, temp); + else + *temp = ((val + offset) * scale) / divider; return 0; } +void sun50i_h5_reg_to_temp(int val, int *temp) +{ + u32 data = (u32)val; + if (data <= 0x500) + *temp = (2590000 - 1452 * data) / 10000; + else + *temp = (2230000 - 1191 * data) / 10000; +} + static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = { .get_temp = &sun4i_gpadc_get_temp, }; @@ -510,6 +534,7 @@ static int sun4i_irq_init(struct platform_device *pdev, const char *name, static const struct gpadc_data sun4i_gpadc_data = { .temp_offset = -1932, .temp_scale = 133, + .temp_divider = 1, .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN, .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT, .adc_chan_select = &sun4i_gpadc_chan_select, @@ -522,6 +547,7 @@ static const struct gpadc_data sun4i_gpadc_data = { static const struct gpadc_data sun5i_gpadc_data = { .temp_offset = -1447, .temp_scale = 100, + .temp_divider = 1, .tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN, .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT, .adc_chan_select = &sun4i_gpadc_chan_select, @@ -534,6 +560,7 @@ static const struct gpadc_data sun5i_gpadc_data = { static const struct gpadc_data sun6i_gpadc_data = { .temp_offset = -1623, .temp_scale = 167, + .temp_divider = 1, .tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN, .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT, .adc_chan_select = &sun6i_gpadc_chan_select, @@ -546,6 +573,7 @@ static const struct gpadc_data sun6i_gpadc_data = { static const struct gpadc_data sun8i_a33_gpadc_data = { .temp_offset = -1662, .temp_scale = 162, + .temp_divider = 1, .tp_mode_en = SUN8I_A23_GPADC_CTRL1_CHOP_TEMP_EN, .temp_data = SUN4I_GPADC_TEMP_DATA, .sample_start = sun4i_gpadc_sample_start, @@ -562,6 +590,34 @@ static const struct gpadc_data sun8i_h3_gpadc_data = { */ .temp_offset = -1791, .temp_scale = -121, + .temp_divider = 1, + .temp_data = SUN8I_H3_GPADC_TEMP_DATA, + .sample_start = sun8i_h3_gpadc_sample_start, + .sample_end = sun8i_h3_gpadc_sample_end, + .has_bus_clk = true, + .has_bus_rst = true, + .has_mod_clk = true, +}; + +static const struct gpadc_data sun50i_a64_gpadc_data = { + .temp_offset = -2170, + .temp_scale = -1000, + .temp_divider = 8560, + .temp_data = SUN8I_H3_GPADC_TEMP_DATA, + .sample_start = sun8i_h3_gpadc_sample_start, + .sample_end = sun8i_h3_gpadc_sample_end, + .has_bus_clk = true, + .has_bus_rst = true, + .has_mod_clk = true, +}; + +static const struct gpadc_data sun50i_h5_gpadc_data = { + /* Not done for now since requires 3 extra fields + and/or a custom temperature conversion function + */ + .temp_offset = -1791, + .temp_scale = -121, + .temp_divider = 1, .temp_data = SUN8I_H3_GPADC_TEMP_DATA, .sample_start = sun8i_h3_gpadc_sample_start, .sample_end = sun8i_h3_gpadc_sample_end, @@ -579,6 +635,14 @@ static const struct of_device_id sun4i_gpadc_of_id[] = { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_h3_gpadc_data, }, + { + .compatible = "allwinner,sun50i-a64-ths", + .data = &sun50i_a64_gpadc_data, + }, + { + .compatible = "allwinner,sun50i-h5-ths", + .data = &sun50i_h5_gpadc_data, + }, { /* sentinel */ } };