mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
saradc: refactor the driver based on the iio sub-system
PD#146222: saradc: refactor the driver based on the iio sub-system the sar adc driver has been moved from directory input/saradc into directory iio/adc, and is refactored base on the standard iio sub-system. the iio sub-system provide two ways to access sar adc resources: 1. standard api for consumer driver it can be found at the file "include/linux/iio/consumer.h". 2. sysfs interface for user space(X: 0-7) - obtain 10-bit sample value: cat sys/bus/iio/devices/iio:device0/in_voltage[X]_input - obtain raw sample value(10-bit or 12-bit): cat sys/bus/iio/devices/iio:device0/in_voltage[X]_raw - obtain mean raw sample value: cat sys/bus/iio/devices/iio:device0/in_voltage[X]_mean_raw test pass on the gxl skt, axg skt, m200. Change-Id: I6c8877c782c51a01993557cabc0d43f212a8e524 Signed-off-by: xingyu.chen <xingyu.chen@amlogic.com>
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
Amlogic Successive Approximation Register (SAR) A/D Converter bindings
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "amlogic, saradc".
|
||||
- clocks: The clock provided by the SoC to the device.
|
||||
- clock-names: Shall be "saradc_clk" for the device.
|
||||
- resets: Shall be "GCLK_IDX_SARADC" for the device.
|
||||
- reg: Physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
|
||||
Optional properties:
|
||||
- status: Shall be "ok" or "okay" if enabled or "disabled" if disabled.
|
||||
Default is "ok".
|
||||
|
||||
Example:
|
||||
saradc: saradc {
|
||||
compatible = "amlogic, saradc";
|
||||
status = "okay";
|
||||
clocks = <&clock CLK_XTAL>;
|
||||
clock-names = "saradc_clk";
|
||||
resets = <&clock GCLK_IDX_SARADC>;
|
||||
reg = <0x0 0xc1108680 0x0 0x30
|
||||
0x0 0xc883c3d8 0x0 0x08>;
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
* Amlogic Meson SAR (Successive Approximation Register) A/D converter
|
||||
|
||||
Required properties:
|
||||
- compatible: depending on the SoC this should be one of:
|
||||
- "amlogic,meson-axg-saradc" for AXG
|
||||
- "amlogic,meson-gxl-saradc" for GXL
|
||||
- "amlogic,meson-gxm-saradc" for GXM
|
||||
- "amlogic,meson-m8b-saradc" for M8B
|
||||
along with the generic "amlogic,meson-saradc"
|
||||
|
||||
- reg: the physical base address and length of the registers
|
||||
|
||||
- interrupts: the interrupt indicating end of sampling
|
||||
|
||||
- clocks: phandle and clock identifier (see clock-names)
|
||||
|
||||
- clock-names: mandatory clocks:
|
||||
- "xtal" for the reference clock (typically XTAL)
|
||||
- "saradc_clk" for the SAR ADC (sampling) clock
|
||||
optional clocks:
|
||||
- "clk81_gate" for the clk81 clock gate
|
||||
|
||||
- #io-channel-cells: must be 1, see ../iio-bindings.txt
|
||||
|
||||
Optional properties:
|
||||
- status: Shall be "ok" or "okay" if enabled or "disabled" if disabled.
|
||||
Default is "ok".
|
||||
|
||||
Example:
|
||||
saradc:saradc {
|
||||
compatible = "amlogic,meson-axg-saradc";
|
||||
status = "okay";
|
||||
#io-channel-cells = <1>;
|
||||
clocks = <&xtal>, <&clkc CLKID_SARADC_GATE>;
|
||||
clock-names = "xtal", "saradc_clk";
|
||||
interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0x0 0xff809000 0x0 0x38>;
|
||||
}
|
||||
@@ -13450,7 +13450,9 @@ F: drivers/amlogic/crypto/*
|
||||
|
||||
AMLOGIC saradc
|
||||
M: Xingyu Chen <xingyu.chen@amlogic.com>
|
||||
F: drivers/amlogic/input/saradc/*
|
||||
F: drivers/amlogic/iio/adc/*
|
||||
F: include/dt-bindings/iio/adc/amlogic-saradc.h
|
||||
F: Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.txt
|
||||
|
||||
AMLOGIC adc_keypad
|
||||
M: Xingyu Chen <xingyu.chen@amlogic.com>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <dt-bindings/clock/meson8b-clkc.h>
|
||||
#include <dt-bindings/gpio/meson8b-gpio.h>
|
||||
#include <dt-bindings/reset/amlogic,meson8b-reset.h>
|
||||
#include <dt-bindings/iio/adc/amlogic-saradc.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/input/meson_rc.h>
|
||||
@@ -802,10 +803,12 @@ dwc2_b {
|
||||
};
|
||||
|
||||
saradc: saradc {
|
||||
compatible = "amlogic, saradc";
|
||||
compatible = "amlogic,meson-m8b-saradc";
|
||||
status = "okay";
|
||||
clocks = <&clkc CLKID_SAR_ADC>;
|
||||
clock-names = "saradc_clk";
|
||||
#io-channel-cells = <1>;
|
||||
clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_SAR_ADC>;
|
||||
clock-names = "xtal", "clk81_gate";
|
||||
interrupts = <0 73 1>;
|
||||
reg = <0xc1108680 0x30>;
|
||||
};
|
||||
|
||||
|
||||
@@ -380,6 +380,8 @@
|
||||
compatible = "amlogic, aml-thermal";
|
||||
device_name = "thermal";
|
||||
#thermal-sensor-cells = <1>;
|
||||
io-channels = <&saradc SARADC_CH6>;
|
||||
io-channel-names = "TEMP_CHAN";
|
||||
cooling_devices {
|
||||
cpufreq_cool_cluster0 {
|
||||
min_state = <768000>;
|
||||
|
||||
@@ -307,6 +307,8 @@
|
||||
compatible = "amlogic, aml-thermal";
|
||||
device_name = "thermal";
|
||||
#thermal-sensor-cells = <1>;
|
||||
io-channels = <&saradc SARADC_CH6>;
|
||||
io-channel-names = "TEMP_CHAN";
|
||||
cooling_devices {
|
||||
cpufreq_cool_cluster0 {
|
||||
min_state = <768000>;
|
||||
|
||||
@@ -225,6 +225,8 @@
|
||||
compatible = "amlogic, aml-thermal";
|
||||
device_name = "thermal";
|
||||
#thermal-sensor-cells = <1>;
|
||||
io-channels = <&saradc SARADC_CH6>;
|
||||
io-channel-names = "TEMP_CHAN";
|
||||
cooling_devices {
|
||||
cpufreq_cool_cluster0 {
|
||||
min_state = <768000>;
|
||||
|
||||
@@ -177,7 +177,6 @@ CONFIG_AMLOGIC_M8B_CLK=y
|
||||
CONFIG_AMLOGIC_CRYPTO=y
|
||||
CONFIG_AMLOGIC_CRYPTO_BLKMV=y
|
||||
CONFIG_AMLOGIC_INPUT=y
|
||||
CONFIG_AMLOGIC_SARADC=y
|
||||
CONFIG_AMLOGIC_REMOTE=y
|
||||
CONFIG_AMLOGIC_MESON_REMOTE=y
|
||||
CONFIG_AMLOGIC_EFUSE=y
|
||||
@@ -211,6 +210,8 @@ CONFIG_AMLOGIC_PMU_OF=y
|
||||
CONFIG_AMLOGIC_PMU=y
|
||||
CONFIG_AMLOGIC_1218=y
|
||||
CONFIG_AMLOGIC_M8B_DVFS=y
|
||||
CONFIG_AMLOGIC_IIO=y
|
||||
CONFIG_AMLOGIC_SARADC=y
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_DMA_CMA=y
|
||||
@@ -300,6 +301,7 @@ CONFIG_CHROME_PLATFORMS=y
|
||||
CONFIG_PM_DEVFREQ=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_MEMORY=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_RESET_CONTROLLER=y
|
||||
CONFIG_GENERIC_PHY=y
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/amlogic,axg-clkc.h>
|
||||
#include <dt-bindings/clock/amlogic,axg-audio-clk.h>
|
||||
#include <dt-bindings/iio/adc/amlogic-saradc.h>
|
||||
#include <dt-bindings/gpio/mesonaxg-gpio.h>
|
||||
#include <dt-bindings/pwm/pwm.h>
|
||||
#include <dt-bindings/pwm/meson.h>
|
||||
@@ -686,6 +687,16 @@
|
||||
interrupts = <0 180 1 0 181 1>;
|
||||
reg = <0x0 0xff63e000 0x0 0x48>;
|
||||
};
|
||||
|
||||
saradc:saradc {
|
||||
compatible = "amlogic,meson-axg-saradc";
|
||||
status = "okay";
|
||||
#io-channel-cells = <1>;
|
||||
clocks = <&xtal>, <&clkc CLKID_SARADC_GATE>;
|
||||
clock-names = "xtal", "saradc_clk";
|
||||
interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0x0 0xff809000 0x0 0x38>;
|
||||
};
|
||||
};/* end of / */
|
||||
|
||||
&pinctrl_aobus {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/reset/amlogic,gxl-reset.h>
|
||||
#include <dt-bindings/clock/amlogic,gxl-clkc.h>
|
||||
#include <dt-bindings/iio/adc/amlogic-saradc.h>
|
||||
#include <dt-bindings/gpio/gxl.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pwm/meson.h>
|
||||
@@ -1010,12 +1011,14 @@ i2c_ao: i2c@c8100500{ /*I2C-AO*/
|
||||
};
|
||||
|
||||
saradc: saradc {
|
||||
compatible = "amlogic, saradc";
|
||||
compatible = "amlogic,meson-gxl-saradc";
|
||||
status = "okay";
|
||||
clocks = <&clkc CLKID_SARADC>;
|
||||
clock-names = "saradc_clk";
|
||||
reg = <0x0 0xc1108680 0x0 0x30
|
||||
0x0 0xc883c3d8 0x0 0x08>;
|
||||
#io-channel-cells = <1>;
|
||||
clocks = <&xtal>, <&clkc CLKID_SARADC>,
|
||||
<&clkc CLKID_SARADC_COMP>;
|
||||
clock-names = "xtal", "clk81_gate", "saradc_clk";
|
||||
interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0x0 0xc1108680 0x0 0x38>;
|
||||
};
|
||||
|
||||
efuse: efuse{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/reset/amlogic,gxl-reset.h>
|
||||
#include <dt-bindings/clock/amlogic,gxl-clkc.h>
|
||||
#include <dt-bindings/iio/adc/amlogic-saradc.h>
|
||||
#include <dt-bindings/gpio/gxl.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pwm/meson.h>
|
||||
@@ -1138,12 +1139,14 @@
|
||||
};
|
||||
|
||||
saradc: saradc {
|
||||
compatible = "amlogic, saradc";
|
||||
compatible = "amlogic,meson-gxl-saradc";
|
||||
status = "okay";
|
||||
clocks = <&clkc CLKID_SARADC>;
|
||||
clock-names = "saradc_clk";
|
||||
reg = <0x0 0xc1108680 0x0 0x30
|
||||
0x0 0xc883c3d8 0x0 0x08>;
|
||||
#io-channel-cells = <1>;
|
||||
clocks = <&xtal>, <&clkc CLKID_SARADC>,
|
||||
<&clkc CLKID_SARADC_COMP>;
|
||||
clock-names = "xtal", "clk81_gate", "saradc_clk";
|
||||
interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0x0 0xc1108680 0x0 0x38>;
|
||||
};
|
||||
|
||||
efuse: efuse{
|
||||
|
||||
@@ -222,8 +222,6 @@ CONFIG_AMLOGIC_CRYPTO=y
|
||||
CONFIG_AMLOGIC_CRYPTO_DMA=y
|
||||
CONFIG_AMLOGIC_INPUT=y
|
||||
CONFIG_AMLOGIC_INPUT_KEYBOARD=y
|
||||
CONFIG_AMLOGIC_ADC_KEYPADS=y
|
||||
CONFIG_AMLOGIC_SARADC=y
|
||||
CONFIG_AMLOGIC_REMOTE=y
|
||||
CONFIG_AMLOGIC_MESON_REMOTE=y
|
||||
CONFIG_AMLOGIC_IRBLASTER=y
|
||||
@@ -301,6 +299,8 @@ CONFIG_AMLOGIC_WIFI=y
|
||||
CONFIG_AMLOGIC_BT_DEVICE=y
|
||||
CONFIG_AMLOGIC_DVB_COMPAT=y
|
||||
CONFIG_AMLOGIC_PCIE=y
|
||||
CONFIG_AMLOGIC_IIO=y
|
||||
CONFIG_AMLOGIC_SARADC=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
@@ -436,6 +436,7 @@ CONFIG_DEVFREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_DEVFREQ_GOV_POWERSAVE=y
|
||||
CONFIG_DEVFREQ_GOV_USERSPACE=y
|
||||
CONFIG_EXTCON=y
|
||||
CONFIG_IIO=y
|
||||
CONFIG_PWM=y
|
||||
CONFIG_ANDROID=y
|
||||
CONFIG_ANDROID_BINDER_IPC=y
|
||||
|
||||
@@ -102,5 +102,7 @@ source "drivers/amlogic/pci/Kconfig"
|
||||
|
||||
source "drivers/amlogic/irblaster/Kconfig"
|
||||
|
||||
source "drivers/amlogic/iio/Kconfig"
|
||||
|
||||
endmenu
|
||||
endif
|
||||
|
||||
@@ -85,3 +85,5 @@ obj-$(CONFIG_AMLOGIC_POWER) += power/
|
||||
obj-$(CONFIG_AMLOGIC_PCIE) += pci/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_IRBLASTER) += irblaster/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_IIO) += iio/
|
||||
|
||||
16
drivers/amlogic/iio/Kconfig
Normal file
16
drivers/amlogic/iio/Kconfig
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# Industrial I/O subsystem configuration
|
||||
#
|
||||
|
||||
menuconfig AMLOGIC_IIO
|
||||
tristate "Industrial I/O support"
|
||||
help
|
||||
The industrial I/O subsystem provides a unified framework for
|
||||
drivers for many different types of embedded sensors using a
|
||||
number of different physical interfaces (i2c, spi, etc).
|
||||
|
||||
if AMLOGIC_IIO
|
||||
|
||||
source "drivers/amlogic/iio/adc/Kconfig"
|
||||
|
||||
endif #IIO
|
||||
5
drivers/amlogic/iio/Makefile
Normal file
5
drivers/amlogic/iio/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for the industrial I/O core.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_IIO) += adc/
|
||||
16
drivers/amlogic/iio/adc/Kconfig
Normal file
16
drivers/amlogic/iio/adc/Kconfig
Normal file
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# ADC drivers
|
||||
#
|
||||
# When adding new entries keep the list in alphabetical order
|
||||
|
||||
menu "Analog to digital converters"
|
||||
|
||||
config AMLOGIC_SARADC
|
||||
bool "Meson SAR ADC support"
|
||||
depends on REGMAP_MMIO
|
||||
depends on IIO
|
||||
default n
|
||||
help
|
||||
Say Y here if you want to use the Meson SAR ADC.
|
||||
|
||||
endmenu
|
||||
7
drivers/amlogic/iio/adc/Makefile
Normal file
7
drivers/amlogic/iio/adc/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
#Makefile for IIO ADC drivers
|
||||
#
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_SARADC) += meson_saradc.o
|
||||
|
||||
|
||||
1214
drivers/amlogic/iio/adc/meson_saradc.c
Normal file
1214
drivers/amlogic/iio/adc/meson_saradc.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,6 @@ if AMLOGIC_INPUT
|
||||
|
||||
source "drivers/amlogic/input/keyboard/Kconfig"
|
||||
|
||||
source "drivers/amlogic/input/saradc/Kconfig"
|
||||
|
||||
source "drivers/amlogic/input/remote/Kconfig"
|
||||
endif
|
||||
|
||||
|
||||
@@ -6,6 +6,4 @@
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_INPUT_KEYBOARD) += keyboard/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_SARADC) += saradc/
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_REMOTE) += remote/
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# Input core configuration
|
||||
#
|
||||
config AMLOGIC_SARADC
|
||||
bool "Meson SAR ADC support"
|
||||
default n
|
||||
help
|
||||
Say Y here if you want to use the Meson SAR ADC.
|
||||
@@ -1,9 +0,0 @@
|
||||
#
|
||||
# Makefile for the input core drivers.
|
||||
#
|
||||
|
||||
# Each configuration option enables a list of files.
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_SARADC) += saradc.o
|
||||
|
||||
|
||||
@@ -1,650 +0,0 @@
|
||||
/*
|
||||
* drivers/amlogic/input/saradc/saradc.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/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/amlogic/saradc.h>
|
||||
#include <linux/amlogic/iomap.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include <asm/barrier.h>
|
||||
#include "saradc_reg.h"
|
||||
|
||||
/* #define ENABLE_DYNAMIC_POWER */
|
||||
#define CLEAN_BUFF_BEFORE_SARADC 1
|
||||
|
||||
/* flag_12bit = 0 : 10 bit */
|
||||
/* flag_12bit = 1 : 12 bit */
|
||||
static char flag_12bit;
|
||||
|
||||
#define saradc_info(x...) dev_info(adc->dev, x)
|
||||
#define saradc_dbg(x...) /* dev_info(adc->dev, x) */
|
||||
#define saradc_err(x...) dev_err(adc->dev, x)
|
||||
|
||||
#define SARADC_STATE_IDLE 0
|
||||
#define SARADC_STATE_BUSY 1
|
||||
#define SARADC_STATE_SUSPEND 2
|
||||
|
||||
const char *ch7_vol[] = {
|
||||
"gnd",
|
||||
"vdd/4",
|
||||
"vdd/2",
|
||||
"vdd*3/4",
|
||||
"vdd",
|
||||
"unused",
|
||||
"unused",
|
||||
"unused"
|
||||
};
|
||||
|
||||
struct saradc {
|
||||
struct device *dev;
|
||||
void __iomem *mem_base;
|
||||
void __iomem *clk_mem_base;
|
||||
struct clk *clk;
|
||||
spinlock_t lock;
|
||||
int ref_val;
|
||||
int ref_nominal;
|
||||
int coef;
|
||||
int state;
|
||||
int ch7_sel;
|
||||
};
|
||||
|
||||
static struct saradc *gp_saradc;
|
||||
|
||||
void setb(
|
||||
void __iomem *mem_base,
|
||||
unsigned int bits_desc,
|
||||
unsigned int bits_val)
|
||||
{
|
||||
unsigned int mem_offset, val;
|
||||
unsigned int bits_offset, bits_mask;
|
||||
|
||||
if (IS_ERR(mem_base))
|
||||
return;
|
||||
mem_offset = of_mem_offset(bits_desc);
|
||||
bits_offset = of_bits_offset(bits_desc);
|
||||
bits_mask = (1L<<of_bits_len(bits_desc))-1;
|
||||
val = readl(mem_base+mem_offset);
|
||||
val &= ~(bits_mask << bits_offset);
|
||||
val |= (bits_val & bits_mask) << bits_offset;
|
||||
writel(val, mem_base+mem_offset);
|
||||
}
|
||||
EXPORT_SYMBOL(setb);
|
||||
|
||||
unsigned int getb(
|
||||
void __iomem *mem_base,
|
||||
unsigned int bits_desc)
|
||||
{
|
||||
unsigned int mem_offset, val;
|
||||
unsigned int bits_offset, bits_mask;
|
||||
|
||||
if (IS_ERR(mem_base))
|
||||
return -1;
|
||||
mem_offset = of_mem_offset(bits_desc);
|
||||
bits_offset = of_bits_offset(bits_desc);
|
||||
bits_mask = (1L<<of_bits_len(bits_desc))-1;
|
||||
val = readl(mem_base+mem_offset);
|
||||
return (val >> bits_offset) & bits_mask;
|
||||
}
|
||||
EXPORT_SYMBOL(getb);
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_M8B_TEMP_SENSOR
|
||||
#ifndef CONFIG_MACH_MESON8
|
||||
void temp_set_trim(unsigned char val)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
tmp = aml_read_cbus(P_HHI_DPLL_TOP_0);
|
||||
tmp = (tmp & (~(1 << 9))) | ((val & 0x1) << 9);
|
||||
aml_write_cbus(P_HHI_DPLL_TOP_0, tmp);
|
||||
}
|
||||
#endif
|
||||
void temp_sensor_adc_init(int triming)
|
||||
{
|
||||
struct saradc *adc = gp_saradc;
|
||||
void __iomem *mem_base;
|
||||
|
||||
mem_base = adc->mem_base;
|
||||
setb(mem_base, TEMP_SELECT, 1);
|
||||
setb(mem_base, TEMP_TRIM, triming & 0xf);
|
||||
#ifndef CONFIG_MACH_MESON8
|
||||
temp_set_trim(triming >> 4);
|
||||
#endif
|
||||
setb(mem_base, TEMP_EN0, 1);
|
||||
setb(mem_base, TEMP_EN1, 1);
|
||||
}
|
||||
EXPORT_SYMBOL(temp_sensor_adc_init);
|
||||
#endif
|
||||
|
||||
static void saradc_power_control(struct saradc *adc, int on)
|
||||
{
|
||||
void __iomem *mem_base = adc->mem_base;
|
||||
|
||||
if (on) {
|
||||
setb(mem_base, BANDGAP_EN, 1);
|
||||
setb(mem_base, ADC_EN, 1);
|
||||
udelay(5);
|
||||
if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB))
|
||||
setb(adc->clk_mem_base, REGC_CLK_EN, 1);
|
||||
else
|
||||
setb(mem_base, CLK_EN, 1);
|
||||
} else {
|
||||
if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB))
|
||||
setb(adc->clk_mem_base, REGC_CLK_EN, 0);
|
||||
else
|
||||
setb(mem_base, CLK_EN, 0);
|
||||
setb(mem_base, ADC_EN, 0);
|
||||
setb(mem_base, BANDGAP_EN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void saradc_reset(struct saradc *adc)
|
||||
{
|
||||
void __iomem *mem_base = adc->mem_base;
|
||||
int clk_div;
|
||||
|
||||
|
||||
if (getb(mem_base, FLAG_INITIALIZED)) {
|
||||
saradc_info("initialized by BL30\n");
|
||||
#ifndef ENABLE_DYNAMIC_POWER
|
||||
saradc_power_control(adc, 1);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
writel(0x84004040, mem_base+SARADC_REG0);
|
||||
writel(0, mem_base+SARADC_CH_LIST);
|
||||
writel(0xaaaa, mem_base+SARADC_AVG_CNTL);
|
||||
if (flag_12bit)
|
||||
writel(0x9b88000a, mem_base+SARADC_REG3);
|
||||
else
|
||||
writel(0x9388000a, mem_base+SARADC_REG3);
|
||||
/* set SARADC_DELAY with 0x190a380a when 32k */
|
||||
writel(0x10a000a, mem_base+SARADC_DELAY);
|
||||
writel(0x3eb1a0c, mem_base+SARADC_AUX_SW);
|
||||
writel(0x3eb1a0c, mem_base+SARADC_AUX_SW);
|
||||
writel(0x8c000c, mem_base+SARADC_CH10_SW);
|
||||
writel(0xc000c, mem_base+SARADC_DETECT_IDLE_SW);
|
||||
|
||||
clk_prepare_enable(adc->clk);
|
||||
clk_div = clk_get_rate(adc->clk) / 1200000;
|
||||
if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB)) {
|
||||
setb(adc->clk_mem_base, REGC_CLK_DIV, clk_div);
|
||||
setb(adc->clk_mem_base, REGC_CLK_SRC, 0);
|
||||
} else {
|
||||
setb(mem_base, CLK_DIV, clk_div);
|
||||
}
|
||||
saradc_info("initialized by kernel, clk_div=%d\n", clk_div);
|
||||
#ifndef ENABLE_DYNAMIC_POWER
|
||||
saradc_power_control(adc, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int saradc_internal_cal(struct saradc *adc)
|
||||
{
|
||||
int val[5], nominal[5] = {0, 256, 512, 768, 1023};
|
||||
int i;
|
||||
|
||||
saradc_info("calibration start:\n");
|
||||
adc->coef = 0;
|
||||
for (i = 0; i < 5; i++) {
|
||||
setb(adc->mem_base, CAL_CNTL, i);
|
||||
udelay(10);
|
||||
val[i] = get_adc_sample(0, CHAN_7);
|
||||
saradc_info("nominal=%d, value=%d\n", nominal[i], val[i]);
|
||||
if (val[i] < 0)
|
||||
goto cal_end;
|
||||
}
|
||||
adc->ref_val = val[2];
|
||||
adc->ref_nominal = nominal[2];
|
||||
if (val[3] > val[1]) {
|
||||
adc->coef = (nominal[3] - nominal[1]) << 12;
|
||||
adc->coef /= val[3] - val[1];
|
||||
}
|
||||
cal_end:
|
||||
saradc_info("calibration end: coef=%d\n", adc->coef);
|
||||
setb(adc->mem_base, CAL_CNTL, 7);
|
||||
adc->ch7_sel = 7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int saradc_get_cal_value(struct saradc *adc, int val)
|
||||
{
|
||||
int nominal;
|
||||
|
||||
/*((nominal - ref_nominal) << 10) / (val - ref_val) = coef*/
|
||||
/*==> nominal = ((val - ref_val) * coef >> 10) + ref_nominal*/
|
||||
|
||||
nominal = val;
|
||||
if ((adc->coef > 0) && (val > 0)) {
|
||||
nominal = (val - adc->ref_val) * adc->coef;
|
||||
nominal >>= 12;
|
||||
nominal += adc->ref_nominal;
|
||||
}
|
||||
if (nominal < 0)
|
||||
nominal = 0;
|
||||
if (nominal > 1023)
|
||||
nominal = 1023;
|
||||
return nominal;
|
||||
}
|
||||
|
||||
static int saradc_get_cal_value_12bit(struct saradc *adc, int val)
|
||||
{
|
||||
int nominal;
|
||||
|
||||
/*((nominal - ref_nominal) << 10) / (val - ref_val) = coef*/
|
||||
/*==> nominal = ((val - ref_val) * coef >> 10) + ref_nominal*/
|
||||
|
||||
nominal = val;
|
||||
if ((adc->coef > 0) && (val > 0)) {
|
||||
nominal = (val - adc->ref_val) * adc->coef;
|
||||
nominal >>= 12;
|
||||
nominal += adc->ref_nominal;
|
||||
}
|
||||
if (nominal < 0)
|
||||
nominal = 0;
|
||||
if (nominal > 4095)
|
||||
nominal = 4095;
|
||||
return nominal;
|
||||
}
|
||||
|
||||
/*if_10bit=1:10bit*/
|
||||
/*if_10bit=0:12bit*/
|
||||
int get_adc_sample_early(int dev_id, int ch, char if_10bit)
|
||||
{
|
||||
struct saradc *adc;
|
||||
void __iomem *mem_base;
|
||||
int value, count, sum;
|
||||
int max = 0;
|
||||
int min = 0x3ff;
|
||||
int min_12bit = 0xfff;
|
||||
unsigned long flags;
|
||||
|
||||
if (!if_10bit)
|
||||
min = min_12bit;
|
||||
|
||||
adc = gp_saradc;
|
||||
mem_base = adc->mem_base;
|
||||
if (!adc || getb(mem_base, FLAG_BUSY_BL30)
|
||||
|| (adc->state != SARADC_STATE_IDLE))
|
||||
return -1;
|
||||
|
||||
spin_lock_irqsave(&adc->lock, flags);
|
||||
adc->state = SARADC_STATE_BUSY;
|
||||
setb(mem_base, FLAG_BUSY_KERNEL, 1);
|
||||
isb();
|
||||
dsb(sy);
|
||||
udelay(1);
|
||||
if (getb(mem_base, FLAG_BUSY_BL30)) {
|
||||
value = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_POWER
|
||||
saradc_power_control(adc, 1);
|
||||
#endif
|
||||
#if CLEAN_BUFF_BEFORE_SARADC
|
||||
count = 0;
|
||||
while (getb(mem_base, FIFO_COUNT) && (count < FIFO_MAX)) {
|
||||
value = readl(mem_base+SARADC_FIFO_RD);
|
||||
count++;
|
||||
}
|
||||
#endif
|
||||
writel(ch, mem_base+SARADC_CH_LIST);
|
||||
setb(mem_base, DETECT_MUX, ch);
|
||||
setb(mem_base, IDLE_MUX, ch);
|
||||
setb(mem_base, SAMPLE_ENGINE_EN, 1);
|
||||
setb(mem_base, START_SAMPLE, 1);
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
udelay(1);
|
||||
if (++count > 1000) {
|
||||
saradc_err("busy, %x\n", readl(mem_base+SARADC_REG0));
|
||||
value = -1;
|
||||
goto end1;
|
||||
}
|
||||
} while (getb(mem_base, ALL_BUSY));
|
||||
|
||||
count = 0;
|
||||
sum = 0;
|
||||
while (getb(mem_base, FIFO_COUNT) && (count < FIFO_MAX)) {
|
||||
value = readl(mem_base+SARADC_FIFO_RD);
|
||||
if (((value>>12) & 0x07) == ch) {
|
||||
if (if_10bit) {
|
||||
if (flag_12bit) {
|
||||
value &= 0xffc;
|
||||
value >>= 2;
|
||||
} else
|
||||
value &= 0x3ff;
|
||||
} else
|
||||
value &= 0xfff;
|
||||
|
||||
if (value > max)
|
||||
max = value;
|
||||
if (value < min)
|
||||
min = value;
|
||||
sum += value;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
value = -1;
|
||||
goto end1;
|
||||
}
|
||||
if (count > 2) {
|
||||
sum -= (max + min);
|
||||
count -= 2;
|
||||
}
|
||||
value = sum / count;
|
||||
saradc_dbg("before cal: %d, count=%d\n", value, count);
|
||||
if (adc->coef) {
|
||||
if (if_10bit)
|
||||
value = saradc_get_cal_value(adc, value);
|
||||
else
|
||||
value = saradc_get_cal_value_12bit(adc, value);
|
||||
saradc_dbg("after cal: %d\n", value);
|
||||
}
|
||||
end1:
|
||||
setb(mem_base, STOP_SAMPLE, 1);
|
||||
setb(mem_base, SAMPLE_ENGINE_EN, 0);
|
||||
#ifdef ENABLE_DYNAMIC_POWER
|
||||
saradc_power_control(0);
|
||||
#endif
|
||||
end:
|
||||
setb(mem_base, FLAG_BUSY_KERNEL, 0);
|
||||
isb();
|
||||
dsb(sy);
|
||||
udelay(1);
|
||||
adc->state = SARADC_STATE_IDLE;
|
||||
spin_unlock_irqrestore(&adc->lock, flags);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
int get_adc_sample(int dev_id, int ch)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = get_adc_sample_early(dev_id, ch, 1);
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL(get_adc_sample);
|
||||
|
||||
int get_adc_sample_12bit(int dev_id, int ch)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = get_adc_sample_early(dev_id, ch, 0);
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL(get_adc_sample_12bit);
|
||||
|
||||
static void __iomem *
|
||||
saradc_get_reg_addr(struct platform_device *pdev, int index)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *reg_addr;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, index);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "reg: cannot obtain I/O memory region");
|
||||
return 0;
|
||||
}
|
||||
if (!devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res), dev_name(&pdev->dev))) {
|
||||
dev_err(&pdev->dev, "Memory region busy\n");
|
||||
return 0;
|
||||
}
|
||||
reg_addr = devm_ioremap_nocache(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
return reg_addr;
|
||||
}
|
||||
|
||||
static ssize_t ch0_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 0));
|
||||
}
|
||||
static ssize_t ch1_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 1));
|
||||
}
|
||||
static ssize_t ch2_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 2));
|
||||
}
|
||||
static ssize_t ch3_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 3));
|
||||
}
|
||||
static ssize_t ch4_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 4));
|
||||
}
|
||||
static ssize_t ch5_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 5));
|
||||
}
|
||||
static ssize_t ch6_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 6));
|
||||
}
|
||||
static ssize_t ch7_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", get_adc_sample(0, 7));
|
||||
}
|
||||
|
||||
static ssize_t ch7_mux_show(struct class *cla,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
int i;
|
||||
int len = 0;
|
||||
struct saradc *adc = gp_saradc;
|
||||
|
||||
len = sprintf(buf, "current: [%d]%s\n\n",
|
||||
adc->ch7_sel, ch7_vol[adc->ch7_sel]);
|
||||
for (i = 0; i < ARRAY_SIZE(ch7_vol); i++)
|
||||
len += sprintf(buf + len, "%d: %s\n", i, ch7_vol[i]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t ch7_mux_store(struct class *cla,
|
||||
struct class_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int val;
|
||||
struct saradc *adc = gp_saradc;
|
||||
|
||||
if (kstrtoint(buf, 0, &val) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (val >= ARRAY_SIZE(ch7_vol))
|
||||
return -EINVAL;
|
||||
|
||||
setb(adc->mem_base, CAL_CNTL, val);
|
||||
adc->ch7_sel = val;
|
||||
|
||||
return count;
|
||||
}
|
||||
static struct class_attribute saradc_class_attrs[] = {
|
||||
__ATTR_RO(ch0),
|
||||
__ATTR_RO(ch1),
|
||||
__ATTR_RO(ch2),
|
||||
__ATTR_RO(ch3),
|
||||
__ATTR_RO(ch4),
|
||||
__ATTR_RO(ch5),
|
||||
__ATTR_RO(ch6),
|
||||
__ATTR_RO(ch7),
|
||||
__ATTR_RW(ch7_mux),
|
||||
__ATTR_NULL
|
||||
};
|
||||
|
||||
static struct class saradc_class = {
|
||||
.name = "saradc",
|
||||
.class_attrs = saradc_class_attrs,
|
||||
};
|
||||
|
||||
static int saradc_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
struct saradc *adc;
|
||||
|
||||
if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXL))
|
||||
flag_12bit = 1;
|
||||
else
|
||||
flag_12bit = 0;
|
||||
|
||||
adc = kzalloc(sizeof(struct saradc), GFP_KERNEL);
|
||||
if (!adc) {
|
||||
err = -ENOMEM;
|
||||
goto end_err;
|
||||
}
|
||||
adc->dev = &pdev->dev;
|
||||
|
||||
if (!pdev->dev.of_node) {
|
||||
err = -EINVAL;
|
||||
goto end_free;
|
||||
}
|
||||
adc->mem_base = saradc_get_reg_addr(pdev, 0);
|
||||
if (!adc->mem_base) {
|
||||
err = -ENODEV;
|
||||
goto end_free;
|
||||
}
|
||||
if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB))
|
||||
adc->clk_mem_base = saradc_get_reg_addr(pdev, 1);
|
||||
|
||||
adc->clk = devm_clk_get(&pdev->dev, "saradc_clk");
|
||||
if (IS_ERR(adc->clk)) {
|
||||
err = -ENOENT;
|
||||
goto end_free;
|
||||
}
|
||||
|
||||
saradc_reset(adc);
|
||||
gp_saradc = adc;
|
||||
dev_set_drvdata(&pdev->dev, adc);
|
||||
spin_lock_init(&adc->lock);
|
||||
adc->state = SARADC_STATE_IDLE;
|
||||
saradc_internal_cal(adc);
|
||||
|
||||
class_register(&saradc_class);
|
||||
|
||||
return 0;
|
||||
end_free:
|
||||
kfree(adc);
|
||||
end_err:
|
||||
dev_err(&pdev->dev, "error=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int saradc_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct saradc *adc = (struct saradc *)dev_get_drvdata(&pdev->dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adc->lock, flags);
|
||||
saradc_power_control(adc, 0);
|
||||
adc->state = SARADC_STATE_SUSPEND;
|
||||
spin_unlock_irqrestore(&adc->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int saradc_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct saradc *adc = (struct saradc *)dev_get_drvdata(&pdev->dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adc->lock, flags);
|
||||
saradc_power_control(adc, 1);
|
||||
adc->state = SARADC_STATE_IDLE;
|
||||
spin_unlock_irqrestore(&adc->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int saradc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct saradc *adc = (struct saradc *)dev_get_drvdata(&pdev->dev);
|
||||
unsigned long flags;
|
||||
|
||||
class_unregister(&saradc_class);
|
||||
spin_lock_irqsave(&adc->lock, flags);
|
||||
saradc_power_control(adc, 0);
|
||||
spin_unlock_irqrestore(&adc->lock, flags);
|
||||
kfree(adc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void saradc_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct saradc *adc = (struct saradc *)dev_get_drvdata(&pdev->dev);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&adc->lock, flags);
|
||||
saradc_power_control(adc, 0);
|
||||
spin_unlock_irqrestore(&adc->lock, flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id saradc_dt_match[] = {
|
||||
{ .compatible = "amlogic, saradc"},
|
||||
{},
|
||||
};
|
||||
#else
|
||||
#define saradc_dt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver saradc_driver = {
|
||||
.probe = saradc_probe,
|
||||
.remove = saradc_remove,
|
||||
.suspend = saradc_suspend,
|
||||
.resume = saradc_resume,
|
||||
.shutdown = saradc_shutdown,
|
||||
.driver = {
|
||||
.name = "saradc",
|
||||
.of_match_table = saradc_dt_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init saradc_init(void)
|
||||
{
|
||||
/* printk(KERN_INFO "SARADC Driver init.\n"); */
|
||||
return platform_driver_register(&saradc_driver);
|
||||
}
|
||||
|
||||
static void __exit saradc_exit(void)
|
||||
{
|
||||
/* printk(KERN_INFO "SARADC Driver exit.\n"); */
|
||||
platform_driver_unregister(&saradc_driver);
|
||||
}
|
||||
|
||||
module_init(saradc_init);
|
||||
module_exit(saradc_exit);
|
||||
|
||||
MODULE_AUTHOR("aml");
|
||||
MODULE_DESCRIPTION("SARADC Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* drivers/amlogic/input/saradc/saradc_reg.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SARADC_REG_H__
|
||||
#define __SARADC_REG_H__
|
||||
|
||||
#define SARADC_REG0 (0<<2)
|
||||
#define SARADC_CH_LIST (1<<2)
|
||||
#define SARADC_AVG_CNTL (2<<2)
|
||||
#define SARADC_REG3 (3<<2)
|
||||
#define SARADC_DELAY (4<<2)
|
||||
#define SARADC_LAST_RD (5<<2)
|
||||
#define SARADC_FIFO_RD (6<<2)
|
||||
#define SARADC_AUX_SW (7<<2)
|
||||
#define SARADC_CH10_SW (8<<2)
|
||||
#define SARADC_DETECT_IDLE_SW (9<<2)
|
||||
#define SARADC_DELTA_10 (10<<2)
|
||||
#define SARADC_REG11 (11<<2)
|
||||
#define P_HHI_DPLL_TOP_0 0x10c6
|
||||
|
||||
#define SAMPLE_ENGINE_EN bits_desc(SARADC_REG0, 0, 1)
|
||||
#define START_SAMPLE bits_desc(SARADC_REG0, 2, 1)
|
||||
#define STOP_SAMPLE bits_desc(SARADC_REG0, 14, 1)
|
||||
#define FIFO_COUNT bits_desc(SARADC_REG0, 21, 5)
|
||||
#define SAMPLE_BUSY bits_desc(SARADC_REG0, 28, 1)
|
||||
#define AVG_BUSY bits_desc(SARADC_REG0, 29, 1)
|
||||
#define DELTA_BUSY bits_desc(SARADC_REG0, 30, 1)
|
||||
#define ALL_BUSY bits_desc(SARADC_REG0, 28, 3)
|
||||
#define CLK_DIV bits_desc(SARADC_REG3, 10, 6)
|
||||
#define ADC_EN bits_desc(SARADC_REG3, 21, 1)
|
||||
#define CAL_CNTL bits_desc(SARADC_REG3, 23, 3)
|
||||
#define FLAG_INITIALIZED bits_desc(SARADC_REG3, 28, 1) /* for bl30 */
|
||||
#define CLK_EN bits_desc(SARADC_REG3, 30, 1)
|
||||
#define FLAG_BUSY_KERNEL bits_desc(SARADC_DELAY, 14, 1) /* for bl30 */
|
||||
#define FLAG_BUSY_BL30 bits_desc(SARADC_DELAY, 15, 1) /* for bl30 */
|
||||
#define IDLE_MUX bits_desc(SARADC_DETECT_IDLE_SW, 7, 3)
|
||||
#define DETECT_MUX bits_desc(SARADC_DETECT_IDLE_SW, 23, 3)
|
||||
#ifdef CONFIG_MACH_MESON8B
|
||||
#define BANDGAP_EN bits_desc(SARADC_DELTA_10, 10, 1)
|
||||
#define TEMP_TRIM bits_desc(SARADC_DELTA_10, 11, 4)
|
||||
#define TEMP_EN0 bits_desc(SARADC_DELTA_10, 15, 1)
|
||||
#define TEMP_EN1 bits_desc(SARADC_DELTA_10, 26, 1)
|
||||
#define TEMP_SELECT bits_desc(SARADC_DELTA_10, 27, 1)
|
||||
#else
|
||||
#define BANDGAP_EN bits_desc(SARADC_REG11, 13, 1)
|
||||
#endif
|
||||
|
||||
/* saradc clock register */
|
||||
#define REGC_CLK_DIV bits_desc(0, 0, 8)
|
||||
#define REGC_CLK_EN bits_desc(0, 8, 1)
|
||||
#define REGC_CLK_SRC bits_desc(0, 9, 3)
|
||||
|
||||
#define FIFO_MAX 32
|
||||
|
||||
#endif
|
||||
@@ -132,7 +132,6 @@ static const char * const log_comment[] = {
|
||||
"pio begin",
|
||||
"pio end"
|
||||
};
|
||||
|
||||
static void spicc_log_init(struct spicc *spicc)
|
||||
{
|
||||
spicc->log = 0;
|
||||
@@ -212,6 +211,37 @@ static void spicc_log_print(struct spicc *spicc)
|
||||
#define spicc_log_print(spicc)
|
||||
#endif
|
||||
|
||||
static void setb(void __iomem *mem_base,
|
||||
unsigned int bits_desc,
|
||||
unsigned int bits_val) {
|
||||
unsigned int mem_offset, val;
|
||||
unsigned int bits_offset, bits_mask;
|
||||
|
||||
if (IS_ERR(mem_base))
|
||||
return;
|
||||
mem_offset = of_mem_offset(bits_desc);
|
||||
bits_offset = of_bits_offset(bits_desc);
|
||||
bits_mask = (1L<<of_bits_len(bits_desc))-1;
|
||||
val = readl(mem_base+mem_offset);
|
||||
val &= ~(bits_mask << bits_offset);
|
||||
val |= (bits_val & bits_mask) << bits_offset;
|
||||
writel(val, mem_base+mem_offset);
|
||||
}
|
||||
|
||||
static unsigned int getb(void __iomem *mem_base,
|
||||
unsigned int bits_desc) {
|
||||
unsigned int mem_offset, val;
|
||||
unsigned int bits_offset, bits_mask;
|
||||
|
||||
if (IS_ERR(mem_base))
|
||||
return -1;
|
||||
mem_offset = of_mem_offset(bits_desc);
|
||||
bits_offset = of_bits_offset(bits_desc);
|
||||
bits_mask = (1L<<of_bits_len(bits_desc))-1;
|
||||
val = readl(mem_base+mem_offset);
|
||||
return (val >> bits_offset) & bits_mask;
|
||||
}
|
||||
|
||||
/* Note this is chip_select enable or disable */
|
||||
void spicc_chip_select(struct spi_device *spi, bool select)
|
||||
{
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#ifndef __SPICC_H__
|
||||
#define __SPICC_H__
|
||||
|
||||
#include <linux/amlogic/saradc.h>
|
||||
|
||||
#define SPICC_FIFO_SIZE 16
|
||||
#define SPICC_DEFAULT_BIT_WIDTH 8
|
||||
#define SPICC_DEFAULT_SPEED_HZ 3000000
|
||||
@@ -41,6 +39,12 @@
|
||||
#define SPICC_REG_ENHANCE_CNTL (14<<2)
|
||||
#define SPICC_REG_ENHANCE_CNTL1 (15<<2)
|
||||
|
||||
#define bits_desc(reg_offset, bits_offset, bits_len) \
|
||||
(((bits_len)<<24)|((bits_offset)<<16)|(reg_offset))
|
||||
#define of_mem_offset(bd) ((bd)&0xffff)
|
||||
#define of_bits_offset(bd) (((bd)>>16)&0xff)
|
||||
#define of_bits_len(bd) (((bd)>>24)&0xff)
|
||||
|
||||
#define CON_ENABLE bits_desc(SPICC_REG_CON, 0, 1)
|
||||
#define CON_MODE bits_desc(SPICC_REG_CON, 1, 1)
|
||||
#define CON_XCH bits_desc(SPICC_REG_CON, 2, 1)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include <linux/amlogic/cpucore_cooling.h>
|
||||
#include <linux/amlogic/gpucore_cooling.h>
|
||||
#include <linux/amlogic/gpu_cooling.h>
|
||||
#include <linux/amlogic/saradc.h>
|
||||
#include <linux/iio/consumer.h>
|
||||
#include <linux/amlogic/efuse.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/amlogic/aml_thermal_hw.h>
|
||||
@@ -72,6 +72,7 @@ struct aml_thermal_sensor {
|
||||
unsigned int cool_dev_num : 9;
|
||||
struct cpumask mask[NUM_CLUSTERS];
|
||||
struct cool_dev *cool_devs;
|
||||
struct iio_channel *temp_chan;
|
||||
struct thermal_zone_device *tzd;
|
||||
};
|
||||
|
||||
@@ -103,7 +104,7 @@ int thermal_firmware_init(void)
|
||||
soc_sensor.chip_trimmed = 0;
|
||||
}
|
||||
if (soc_sensor.chip_trimmed) {
|
||||
temp_sensor_adc_init(soc_sensor.ts_c);
|
||||
iio_write_channel_raw(soc_sensor.temp_chan, soc_sensor.ts_c);
|
||||
return 0;
|
||||
} else
|
||||
return -1;
|
||||
@@ -113,17 +114,19 @@ EXPORT_SYMBOL(thermal_firmware_init);
|
||||
|
||||
int get_cpu_temp(void)
|
||||
{
|
||||
int ret = TEMP_NOT_TRIMMED, tempa;
|
||||
int ret;
|
||||
int tempa;
|
||||
int tval = TEMP_NOT_TRIMMED;
|
||||
|
||||
if (soc_sensor.chip_trimmed) {
|
||||
ret = get_adc_sample(0, TEMP_ADC_CHANNEL);
|
||||
ret = iio_read_channel_processed(soc_sensor.temp_chan, &tval);
|
||||
if (ret >= 0) {
|
||||
tempa = (10 * (ret - soc_sensor.fix_value)) / 32 + 27;
|
||||
ret = tempa;
|
||||
tempa = (10 * (tval - soc_sensor.fix_value)) / 32 + 27;
|
||||
tval = tempa;
|
||||
} else
|
||||
ret = TEMP_ADC_ERROR;
|
||||
tval = TEMP_ADC_ERROR;
|
||||
}
|
||||
return ret;
|
||||
return tval;
|
||||
}
|
||||
EXPORT_SYMBOL(get_cpu_temp);
|
||||
|
||||
@@ -357,6 +360,10 @@ static int aml_thermal_probe(struct platform_device *pdev)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
soc_sensor.temp_chan = devm_iio_channel_get(&pdev->dev, "TEMP_CHAN");
|
||||
if (IS_ERR(soc_sensor.temp_chan))
|
||||
return PTR_ERR(soc_sensor.temp_chan);
|
||||
|
||||
if (thermal_firmware_init() < 0) {
|
||||
dev_err(&pdev->dev, "chip is not trimmed, disable thermal\n");
|
||||
return -EINVAL;
|
||||
|
||||
19
include/dt-bindings/iio/adc/amlogic-saradc.h
Normal file
19
include/dt-bindings/iio/adc/amlogic-saradc.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* This header provides constants for configuring the AMLOGIC SAR ADC
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_IIO_ADC_AMLOGIC_H
|
||||
#define _DT_BINDINGS_IIO_ADC_AMLOGIC_H
|
||||
|
||||
#define SARADC_CH0 0
|
||||
#define SARADC_CH1 1
|
||||
#define SARADC_CH2 2
|
||||
#define SARADC_CH3 3
|
||||
#define SARADC_CH4 4
|
||||
#define SARADC_CH5 5
|
||||
#define SARADC_CH6 6
|
||||
#define SARADC_CH7 7
|
||||
|
||||
#define SARADC_CH_NUM 8
|
||||
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* include/linux/amlogic/saradc.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AML_SARADC_H__
|
||||
#define __AML_SARADC_H__
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#define SARADC_DEV_NUM 1
|
||||
|
||||
enum {
|
||||
CHAN_0 = 0,
|
||||
CHAN_1,
|
||||
CHAN_2,
|
||||
CHAN_3,
|
||||
CHAN_4,
|
||||
CHAN_5,
|
||||
CHAN_6,
|
||||
CHAN_7,
|
||||
SARADC_CHAN_NUM,
|
||||
};
|
||||
|
||||
extern int get_adc_sample(int dev_id, int ch);
|
||||
extern int get_adc_sample_12bit(int dev_id, int ch);
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_M8B_TEMP_SENSOR
|
||||
extern void temp_sensor_adc_init(int triming);
|
||||
#endif
|
||||
|
||||
#define bits_desc(reg_offset, bits_offset, bits_len) \
|
||||
(((bits_len)<<24)|((bits_offset)<<16)|(reg_offset))
|
||||
#define of_mem_offset(bd) ((bd)&0xffff)
|
||||
#define of_bits_offset(bd) (((bd)>>16)&0xff)
|
||||
#define of_bits_len(bd) (((bd)>>24)&0xff)
|
||||
|
||||
extern void setb(void __iomem *mem_base, unsigned int bits_desc,
|
||||
unsigned int bits_val);
|
||||
extern unsigned int getb(void __iomem *mem_base, unsigned int bits_desc);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user