adc: Introduce new mcux adc16 driver

Adds a shim layer around the mcux adc16 driver to adapt it to the Zephyr
adc interface.

Jira: ZEP-1396

Signed-off-by: Maureen Helm <maureen.helm@nxp.com>
This commit is contained in:
Maureen Helm 2017-06-05 15:33:45 -05:00 committed by Kumar Gala
commit 8ff51559da
5 changed files with 170 additions and 0 deletions

View file

@ -64,6 +64,12 @@ config HAS_LPSCI
help help
Set if the low power uart (LPSCI) module is present in the SoC. Set if the low power uart (LPSCI) module is present in the SoC.
config HAS_ADC16
bool
default n
help
Set if the 16-bit ADC (ADC16) module is present in the SoC.
config HAS_SYSMPU config HAS_SYSMPU
bool "Enable MPU" bool "Enable MPU"
depends on CPU_HAS_MPU depends on CPU_HAS_MPU

View file

@ -303,4 +303,12 @@ endif
endif # ADC_QMSI || ADC_QMSI_SS endif # ADC_QMSI || ADC_QMSI_SS
config ADC_MCUX_ADC16
bool "MCUX ADC16 driver"
depends on HAS_MCUX && HAS_ADC16
select HAS_DTS_ADC
default n
help
Enable the MCUX ADC16 driver.
endif # ADC endif # ADC

View file

@ -1,4 +1,5 @@
obj-$(CONFIG_ADC_DW) += adc_dw.o obj-$(CONFIG_ADC_DW) += adc_dw.o
obj-$(CONFIG_ADC_MCUX_ADC16) += adc_mcux_adc16.o
obj-$(CONFIG_ADC_TI_ADC108S102) += adc_ti_adc108s102.o obj-$(CONFIG_ADC_TI_ADC108S102) += adc_ti_adc108s102.o
obj-$(CONFIG_ADC_QMSI) += adc_qmsi.o obj-$(CONFIG_ADC_QMSI) += adc_qmsi.o
obj-$(CONFIG_ADC_QMSI_SS) += adc_qmsi_ss.o obj-$(CONFIG_ADC_QMSI_SS) += adc_qmsi_ss.o

View file

@ -0,0 +1,154 @@
/*
* Copyright (c) 2017, NXP
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <errno.h>
#include <adc.h>
#include <soc.h>
#include <fsl_adc16.h>
struct mcux_adc16_config {
ADC_Type *base;
void (*irq_config_func)(struct device *dev);
};
struct mcux_adc16_data {
struct k_sem sync;
u32_t channel_group;
u32_t result;
};
static void mcux_adc16_enable(struct device *dev)
{
ARG_UNUSED(dev);
}
static void mcux_adc16_disable(struct device *dev)
{
ARG_UNUSED(dev);
}
static int mcux_adc16_read(struct device *dev, struct adc_seq_table *seq_table)
{
const struct mcux_adc16_config *config = dev->config->config_info;
struct mcux_adc16_data *data = dev->driver_data;
ADC_Type *base = config->base;
struct adc_seq_entry *entry = seq_table->entries;
adc16_channel_config_t channel_config;
u32_t channel_group = 0;
int i;
channel_config.enableInterruptOnConversionCompleted = true;
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
channel_config.enableDifferentialConversion = false;
#endif
for (i = 0; i < seq_table->num_entries; i++) {
if (entry->buffer_length < sizeof(data->result)) {
return -EINVAL;
}
channel_config.channelNumber = entry->channel_id;
ADC16_SetChannelConfig(base, channel_group, &channel_config);
data->channel_group = channel_group;
k_sem_take(&data->sync, K_FOREVER);
memcpy(entry->buffer, &data->result, sizeof(data->result));
entry++;
}
return 0;
}
static void mcux_adc16_isr(void *arg)
{
struct device *dev = (struct device *)arg;
const struct mcux_adc16_config *config = dev->config->config_info;
struct mcux_adc16_data *data = dev->driver_data;
ADC_Type *base = config->base;
u32_t channel_group = data->channel_group;
data->result = ADC16_GetChannelConversionValue(base, channel_group);
k_sem_give(&data->sync);
}
static int mcux_adc16_init(struct device *dev)
{
const struct mcux_adc16_config *config = dev->config->config_info;
struct mcux_adc16_data *data = dev->driver_data;
ADC_Type *base = config->base;
adc16_config_t adc_config;
k_sem_init(&data->sync, 0, UINT_MAX);
ADC16_GetDefaultConfig(&adc_config);
ADC16_Init(base, &adc_config);
ADC16_EnableHardwareTrigger(base, false);
ADC16_SetHardwareAverage(base, kADC16_HardwareAverageCount4);
config->irq_config_func(dev);
return 0;
}
static const struct adc_driver_api mcux_adc16_driver_api = {
.enable = mcux_adc16_enable,
.disable = mcux_adc16_disable,
.read = mcux_adc16_read,
};
#if CONFIG_ADC_0
static void mcux_adc16_config_func_0(struct device *dev);
static const struct mcux_adc16_config mcux_adc16_config_0 = {
.base = (ADC_Type *)CONFIG_ADC_0_BASE_ADDRESS,
.irq_config_func = mcux_adc16_config_func_0,
};
static struct mcux_adc16_data mcux_adc16_data_0;
DEVICE_AND_API_INIT(mcux_adc16_0, CONFIG_ADC_0_NAME, &mcux_adc16_init,
&mcux_adc16_data_0, &mcux_adc16_config_0,
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&mcux_adc16_driver_api);
static void mcux_adc16_config_func_0(struct device *dev)
{
IRQ_CONNECT(CONFIG_ADC_0_IRQ, CONFIG_ADC_0_IRQ_PRI,
mcux_adc16_isr, DEVICE_GET(mcux_adc16_0), 0);
irq_enable(CONFIG_ADC_0_IRQ);
}
#endif /* CONFIG_ADC_0 */
#if CONFIG_ADC_1
static void mcux_adc16_config_func_1(struct device *dev);
static const struct mcux_adc16_config mcux_adc16_config_1 = {
.base = (ADC_Type *)CONFIG_ADC_1_BASE_ADDRESS,
.irq_config_func = mcux_adc16_config_func_1,
};
static struct mcux_adc16_data mcux_adc16_data_1;
DEVICE_AND_API_INIT(mcux_adc16_1, CONFIG_ADC_1_NAME, &mcux_adc16_init,
&mcux_adc16_data_1, &mcux_adc16_config_1,
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&mcux_adc16_driver_api);
static void mcux_adc16_config_func_1(struct device *dev)
{
IRQ_CONNECT(CONFIG_ADC_1_IRQ, CONFIG_ADC_1_IRQ_PRI,
mcux_adc16_isr, DEVICE_GET(mcux_adc16_1), 0);
irq_enable(CONFIG_ADC_1_IRQ);
}
#endif /* CONFIG_ADC_1 */

View file

@ -4,6 +4,7 @@
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
obj-$(CONFIG_ADC_MCUX_ADC16) += fsl_adc16.o
obj-$(CONFIG_ETH_MCUX) += fsl_enet.o obj-$(CONFIG_ETH_MCUX) += fsl_enet.o
obj-$(CONFIG_I2C_MCUX) += fsl_i2c.o obj-$(CONFIG_I2C_MCUX) += fsl_i2c.o
obj-$(CONFIG_RANDOM_MCUX_RNGA) += fsl_rnga.o obj-$(CONFIG_RANDOM_MCUX_RNGA) += fsl_rnga.o