/** * struct at91_adc_platform - at91-sama5d2 platform information struct * @layout: pointer to the reg layout struct * @adc_channels: pointer to an array of channels for registering in * the iio subsystem * @nr_channels: number of physical channels available * @touch_chan_x: index of the touchscreen X channel * @touch_chan_y: index of the touchscreen Y channel * @touch_chan_p: index of the touchscreen P channel * @max_channels: number of total channels * @max_index: highest channel index (highest index may be higher * than the total channel number) * @hw_trig_cnt: number of possible hardware triggers * @osr_mask: oversampling ratio bitmask on EMR register * @oversampling_avail: available oversampling values * @oversampling_avail_no: number of available oversampling values * @chan_realbits: realbits for registered channels * @temp_chan: temperature channel index * @temp_sensor: temperature sensor supported
*/ struct at91_adc_platform { conststruct at91_adc_reg_layout *layout; conststruct iio_chan_spec (*adc_channels)[]; unsignedint nr_channels; unsignedint touch_chan_x; unsignedint touch_chan_y; unsignedint touch_chan_p; unsignedint max_channels; unsignedint max_index; unsignedint hw_trig_cnt; unsignedint osr_mask; unsignedint oversampling_avail[5]; unsignedint oversampling_avail_no; unsignedint chan_realbits; unsignedint temp_chan; bool temp_sensor;
};
/** * struct at91_adc_temp_sensor_clb - at91-sama5d2 temperature sensor * calibration data structure * @p1: P1 calibration temperature * @p4: P4 calibration voltage * @p6: P6 calibration voltage
*/ struct at91_adc_temp_sensor_clb {
u32 p1;
u32 p4;
u32 p6;
};
/** * enum at91_adc_ts_clb_idx - calibration indexes in NVMEM buffer * @AT91_ADC_TS_CLB_IDX_P1: index for P1 * @AT91_ADC_TS_CLB_IDX_P4: index for P4 * @AT91_ADC_TS_CLB_IDX_P6: index for P6 * @AT91_ADC_TS_CLB_IDX_MAX: max index for temperature calibration packet in OTP
*/ enum at91_adc_ts_clb_idx {
AT91_ADC_TS_CLB_IDX_P1 = 2,
AT91_ADC_TS_CLB_IDX_P4 = 5,
AT91_ADC_TS_CLB_IDX_P6 = 7,
AT91_ADC_TS_CLB_IDX_MAX = 19,
};
/* Temperature sensor calibration - Vtemp voltage sensitivity to temperature. */ #define AT91_ADC_TS_VTEMP_DT (2080U)
/** * struct at91_adc_soc_info - at91-sama5d2 soc information struct * @startup_time: device startup time * @min_sample_rate: minimum sample rate in Hz * @max_sample_rate: maximum sample rate in Hz * @platform: pointer to the platform structure * @temp_sensor_clb: temperature sensor calibration data structure
*/ struct at91_adc_soc_info { unsigned startup_time; unsigned min_sample_rate; unsigned max_sample_rate; conststruct at91_adc_platform *platform; struct at91_adc_temp_sensor_clb temp_sensor_clb;
};
/** * struct at91_adc_dma - at91-sama5d2 dma information struct * @dma_chan: the dma channel acquired * @rx_buf: dma coherent allocated area * @rx_dma_buf: dma handler for the buffer * @phys_addr: physical address of the ADC base register * @buf_idx: index inside the dma buffer where reading was last done * @rx_buf_sz: size of buffer used by DMA operation * @watermark: number of conversions to copy before DMA triggers irq * @dma_ts: hold the start timestamp of dma operation
*/ struct at91_adc_dma { struct dma_chan *dma_chan;
u8 *rx_buf;
dma_addr_t rx_dma_buf;
phys_addr_t phys_addr; int buf_idx; int rx_buf_sz; int watermark;
s64 dma_ts;
};
/** * struct at91_adc_touch - at91-sama5d2 touchscreen information struct * @sample_period_val: the value for periodic trigger interval * @touching: is the pen touching the screen or not * @x_pos: temporary placeholder for pressure computation * @channels_bitmask: bitmask with the touchscreen channels enabled * @workq: workqueue for buffer data pushing
*/ struct at91_adc_touch {
u16 sample_period_val; bool touching;
u16 x_pos; unsignedlong channels_bitmask; struct work_struct workq;
};
/** * struct at91_adc_temp - at91-sama5d2 temperature information structure * @sample_period_val: sample period value * @saved_sample_rate: saved sample rate * @saved_oversampling: saved oversampling
*/ struct at91_adc_temp {
u16 sample_period_val;
u16 saved_sample_rate;
u16 saved_oversampling;
};
struct at91_adc_state { void __iomem *base; int irq; struct clk *per_clk; struct regulator *reg; struct regulator *vref; int vref_uv; unsignedint current_sample_rate; struct iio_trigger *trig; conststruct at91_adc_trigger *selected_trig; conststruct iio_chan_spec *chan; bool conversion_done;
u32 conversion_value; unsignedint oversampling_ratio; struct at91_adc_soc_info soc_info;
wait_queue_head_t wq_data_available; struct at91_adc_dma dma_st; struct at91_adc_touch touch_st; struct at91_adc_temp temp_st; struct iio_dev *indio_dev; struct device *dev; /* We assume 32 channels for now, has to be increased if needed. */
IIO_DECLARE_BUFFER_WITH_TS(u16, buffer, 32); /* * lock to prevent concurrent 'single conversion' requests through * sysfs.
*/ struct mutex lock;
};
staticvoid at91_adc_eoc_dis(struct at91_adc_state *st, unsignedint channel)
{ /* * On some products having the EOC bits in a separate register, * errata recommends not writing this register (EOC_IDR). * On products having the EOC bits in the IDR register, it's fine to write it.
*/ if (!st->soc_info.platform->layout->EOC_IDR)
at91_adc_writel(st, IDR, BIT(channel));
}
staticint at91_adc_config_emr(struct at91_adc_state *st,
u32 oversampling_ratio, u32 trackx)
{ /* configure the extended mode register */ unsignedint emr, osr; unsignedint osr_mask = st->soc_info.platform->osr_mask; int i, ret;
/* Check against supported oversampling values. */ for (i = 0; i < st->soc_info.platform->oversampling_avail_no; i++) { if (oversampling_ratio == st->soc_info.platform->oversampling_avail[i]) break;
} if (i == st->soc_info.platform->oversampling_avail_no) return -EINVAL;
/* select oversampling ratio from configuration */ switch (oversampling_ratio) { case 1:
osr = AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_1SAMPLES,
osr_mask); break; case 4:
osr = AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_4SAMPLES,
osr_mask); break; case 16:
osr = AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_16SAMPLES,
osr_mask); break; case 64:
osr = AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_64SAMPLES,
osr_mask); break; case 256:
osr = AT91_SAMA5D2_EMR_OSR(AT91_SAMA5D2_EMR_OSR_256SAMPLES,
osr_mask); break;
}
ret = pm_runtime_resume_and_get(st->dev); if (ret < 0) return ret;
emr = at91_adc_readl(st, EMR); /* select oversampling per single trigger event */
emr |= AT91_SAMA5D2_EMR_ASTE(1); /* delete leftover content if it's the case */
emr &= ~(osr_mask | AT91_SAMA5D2_TRACKX_MASK); /* Update osr and trackx. */
emr |= osr | AT91_SAMA5D2_TRACKX(trackx);
at91_adc_writel(st, EMR, emr);
/* * We have nbits of real data and channel is registered as * st->soc_info.platform->chan_realbits, so shift left diff bits.
*/
diff = st->soc_info.platform->chan_realbits - nbits;
*val <<= diff;
return IIO_VAL_INT;
}
staticvoid at91_adc_adjust_val_osr_array(struct at91_adc_state *st, void *buf, int len)
{ int i = 0, val;
u16 *buf_u16 = (u16 *) buf;
/* * We are converting each two bytes (each sample). * First convert the byte based array to u16, and convert each sample * separately. * Each value is two bytes in an array of chars, so to not shift * more than we need, save the value separately. * len is in bytes, so divide by two to get number of samples.
*/ while (i < len / 2) {
val = buf_u16[i];
at91_adc_adjust_val_osr(st, &val);
buf_u16[i] = val;
i++;
}
}
if (state) {
ret = pm_runtime_resume_and_get(st->dev); if (ret < 0) return ret;
} else { /* disabling touch IRQs and setting mode to no touch enabled */
at91_adc_writel(st, IDR,
AT91_SAMA5D2_IER_PEN | AT91_SAMA5D2_IER_NOPEN);
at91_adc_writel(st, TSMR, 0);
pm_runtime_mark_last_busy(st->dev);
pm_runtime_put_autosuspend(st->dev); return 0;
} /* * debounce time is in microseconds, we need it in milliseconds to * multiply with kilohertz, so, divide by 1000, but after the multiply. * round up to make sure pendbc is at least 1
*/
pendbc = round_up(AT91_SAMA5D2_TOUCH_PEN_DETECT_DEBOUNCE_US *
clk_khz / 1000, 1);
/* get the required exponent */ while (pendbc >> i++)
;
static u16 at91_adc_touch_pos(struct at91_adc_state *st, int reg)
{
u32 val = 0;
u32 scale, result, pos;
/* * to obtain the actual position we must divide by scale * and multiply with max, where * max = 2^AT91_SAMA5D2_MAX_POS_BITS - 1
*/ /* first half of register is the x or y, second half is the scale */ if (reg == st->soc_info.platform->layout->XPOSR)
val = at91_adc_readl(st, XPOSR); elseif (reg == st->soc_info.platform->layout->YPOSR)
val = at91_adc_readl(st, YPOSR);
if (!val)
dev_dbg(&st->indio_dev->dev, "pos is 0\n");
pos = val & AT91_SAMA5D2_XYZ_MASK;
result = (pos << AT91_SAMA5D2_MAX_POS_BITS) - pos;
scale = (val >> 16) & AT91_SAMA5D2_XYZ_MASK; if (scale == 0) {
dev_err(&st->indio_dev->dev, "scale is 0\n"); return 0;
}
result /= scale;
/* * The pressure from device grows down, minimum is 0xFFFF, maximum 0x0. * We compute it this way, but let's return it in the expected way, * growing from 0 to 0xFFFF.
*/ return 0xFFFF - pres;
}
staticint at91_adc_dma_size_done(struct at91_adc_state *st)
{ struct dma_tx_state state; enum dma_status status; int i, size;
status = dmaengine_tx_status(st->dma_st.dma_chan,
st->dma_st.dma_chan->cookie,
&state); if (status != DMA_IN_PROGRESS) return 0;
/* Transferred length is size in bytes from end of buffer */
i = st->dma_st.rx_buf_sz - state.residue;
/* Return available bytes */ if (i >= st->dma_st.buf_idx)
size = i - st->dma_st.buf_idx; else
size = st->dma_st.rx_buf_sz + i - st->dma_st.buf_idx; return size;
}
/* consider current time as DMA start time for timestamps */
st->dma_st.dma_ts = iio_get_time_ns(indio_dev);
dev_dbg(&indio_dev->dev, "DMA cyclic started\n");
return 0;
}
staticbool at91_adc_buffer_check_use_irq(struct iio_dev *indio, struct at91_adc_state *st)
{ /* if using DMA, we do not use our own IRQ (we use DMA-controller) */ if (st->dma_st.dma_chan) returnfalse; /* if the trigger is not ours, then it has its own IRQ */ if (iio_trigger_validate_own_device(indio->trig, indio)) returnfalse; returntrue;
}
/* check if we are enabling triggered buffer or the touchscreen */ if (at91_adc_current_chan_is_touch(indio_dev)) return at91_adc_configure_touch(st, true);
/* if we are not in triggered mode, we cannot enable the buffer. */ if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES)) return -EINVAL;
ret = pm_runtime_resume_and_get(st->dev); if (ret < 0) return ret;
/* we continue with the triggered buffer */
ret = at91_adc_dma_start(indio_dev); if (ret) {
dev_err(&indio_dev->dev, "buffer prepare failed\n"); goto pm_runtime_put;
}
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->num_channels) { struct iio_chan_spec const *chan =
at91_adc_chan_get(indio_dev, bit); if (!chan) continue; /* these channel types cannot be handled by this trigger */ if (chan->type == IIO_POSITIONRELATIVE ||
chan->type == IIO_PRESSURE ||
chan->type == IIO_TEMP) continue;
at91_adc_cor(st, chan);
at91_adc_writel(st, CHER, BIT(chan->channel));
}
if (at91_adc_buffer_check_use_irq(indio_dev, st))
at91_adc_writel(st, IER, AT91_SAMA5D2_IER_DRDY);
/* check if we are disabling triggered buffer or the touchscreen */ if (at91_adc_current_chan_is_touch(indio_dev)) return at91_adc_configure_touch(st, false);
/* if we are not in triggered mode, nothing to do here */ if (!(iio_device_get_current_mode(indio_dev) & INDIO_ALL_TRIGGERED_MODES)) return -EINVAL;
ret = pm_runtime_resume_and_get(st->dev); if (ret < 0) return ret;
/* * For each enable channel we must disable it in hardware. * In the case of DMA, we must read the last converted value * to clear EOC status and not get a possible interrupt later. * This value is being read by DMA from LCDR anyway, so it's not lost.
*/
for_each_set_bit(bit, indio_dev->active_scan_mask,
indio_dev->num_channels) { struct iio_chan_spec const *chan =
at91_adc_chan_get(indio_dev, bit);
if (!chan) continue; /* these channel types are virtual, no need to do anything */ if (chan->type == IIO_POSITIONRELATIVE ||
chan->type == IIO_PRESSURE ||
chan->type == IIO_TEMP) continue;
at91_adc_writel(st, CHDR, BIT(chan->channel));
if (st->dma_st.dma_chan)
at91_adc_read_chan(st, chan->address);
}
if (at91_adc_buffer_check_use_irq(indio_dev, st))
at91_adc_writel(st, IDR, AT91_SAMA5D2_IER_DRDY);
/* read overflow register to clear possible overflow status */
at91_adc_readl(st, OVER);
/* if we are using DMA we must clear registers and end DMA */ if (st->dma_st.dma_chan)
dmaengine_terminate_sync(st->dma_st.dma_chan);
/* * Check if the conversion is ready. If not, wait a little bit, and * in case of timeout exit with an error.
*/ while (((eoc & mask) != mask) && timeout) {
at91_adc_irq_status(st, &status, &eoc);
at91_adc_irq_mask(st, &imr, &eoc_imr);
usleep_range(50, 100);
timeout--;
}
/* Cannot read data, not ready. Continue without reporting data */ if (!timeout) return;
if (!chan) continue; /* * Our external trigger only supports the voltage channels. * In case someone requested a different type of channel * just put zeroes to buffer. * This should not happen because we check the scan mode * and scan mask when we enable the buffer, and we don't allow * the buffer to start with a mixed mask (voltage and something * else). * Thus, emit a warning.
*/ if (chan->type == IIO_VOLTAGE) {
val = at91_adc_read_chan(st, chan->address);
at91_adc_adjust_val_osr(st, &val);
st->buffer[i] = val;
} else {
st->buffer[i] = 0;
WARN(true, "This trigger cannot handle this type of channel");
}
i++;
}
iio_push_to_buffers_with_timestamp(indio_dev, st->buffer,
pf->timestamp);
}
u32 status = at91_adc_readl(st, ISR); /* if we reached this point, we cannot sample faster */ if (status & AT91_SAMA5D2_IER_GOVRE)
pr_info_ratelimited("%s: conversion overrun detected\n",
indio_dev->name);
/* * interval between samples is total time since last transfer handling * divided by the number of samples (total size divided by sample size)
*/
interval = div_s64((ns - st->dma_st.dma_ts), sample_count);
while (transferred_len >= sample_size) { /* * for all the values in the current sample, * adjust the values inside the buffer for oversampling
*/
at91_adc_adjust_val_osr_array(st,
&st->dma_st.rx_buf[st->dma_st.buf_idx],
sample_size);
iio_push_to_buffers_with_timestamp(indio_dev,
(st->dma_st.rx_buf + st->dma_st.buf_idx),
(st->dma_st.dma_ts + interval * sample_index)); /* adjust remaining length */
transferred_len -= sample_size; /* adjust buffer index */
st->dma_st.buf_idx += sample_size; /* in case of reaching end of buffer, reset index */ if (st->dma_st.buf_idx >= st->dma_st.rx_buf_sz)
st->dma_st.buf_idx = 0;
sample_index++;
} /* adjust saved time for next transfer handling */
st->dma_st.dma_ts = iio_get_time_ns(indio_dev);
}
/* * If it's not our trigger, start a conversion now, as we are * actually polling the trigger now.
*/ if (iio_trigger_validate_own_device(indio_dev->trig, indio_dev))
at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
if (st->dma_st.dma_chan)
at91_adc_trigger_handler_dma(indio_dev); else
at91_adc_trigger_handler_nodma(indio_dev, pf);
if (chan->type == IIO_POSITIONRELATIVE)
at91_adc_read_position(st, chan->channel, &val); elseif (chan->type == IIO_PRESSURE)
at91_adc_read_pressure(st, chan->channel, &val); else continue;
st->buffer[i] = val;
i++;
} /* * Schedule work to push to buffers. * This is intended to push to the callback buffer that another driver * registered. We are still in a handler from our IRQ. If we push * directly, it means the other driver has it's callback called * from our IRQ context. Which is something we better avoid. * Let's schedule it after our IRQ is completed.
*/
schedule_work(&st->touch_st.workq);
}
if (!(status & imr) && !(eoc & eoc_imr)) return IRQ_NONE; if (status & AT91_SAMA5D2_IER_PEN) { /* pen detected IRQ */
at91_adc_pen_detect_interrupt(st);
} elseif ((status & AT91_SAMA5D2_IER_NOPEN)) { /* nopen detected IRQ */
at91_adc_no_pen_detect_interrupt(indio);
} elseif ((status & AT91_SAMA5D2_ISR_PENS) &&
((status & rdy_mask) == rdy_mask)) { /* periodic trigger IRQ - during pen sense */
at91_adc_touch_data_handler(indio);
} elseif (status & AT91_SAMA5D2_ISR_PENS) { /* * touching, but the measurements are not ready yet. * read and ignore.
*/
status = at91_adc_readl(st, XPOSR);
status = at91_adc_readl(st, YPOSR);
status = at91_adc_readl(st, PRESSR);
} elseif (iio_buffer_enabled(indio) &&
(status & AT91_SAMA5D2_IER_DRDY)) { /* triggered buffer without DMA */
disable_irq_nosync(irq);
iio_trigger_poll(indio->trig);
} elseif (iio_buffer_enabled(indio) && st->dma_st.dma_chan) { /* triggered buffer with DMA - should not happen */
disable_irq_nosync(irq);
WARN(true, "Unexpected irq occurred\n");
} elseif (!iio_buffer_enabled(indio)) { /* software requested conversion */
st->conversion_value = at91_adc_read_chan(st, st->chan->address);
st->conversion_done = true;
wake_up_interruptible(&st->wq_data_available);
} return IRQ_HANDLED;
}
/* This needs to be called with direct mode claimed and st->lock locked. */ staticint at91_adc_read_info_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val)
{ struct at91_adc_state *st = iio_priv(indio_dev);
u16 tmp_val; int ret;
ret = pm_runtime_resume_and_get(st->dev); if (ret < 0) return ret;
/* * Keep in mind that we cannot use software trigger or touchscreen * if external trigger is enabled
*/ if (chan->type == IIO_POSITIONRELATIVE) {
ret = at91_adc_read_position(st, chan->channel,
&tmp_val);
*val = tmp_val; if (ret > 0)
ret = at91_adc_adjust_val_osr(st, val);
goto pm_runtime_put;
} if (chan->type == IIO_PRESSURE) {
ret = at91_adc_read_pressure(st, chan->channel,
&tmp_val);
*val = tmp_val; if (ret > 0)
ret = at91_adc_adjust_val_osr(st, val);
goto pm_runtime_put;
}
/* in this case we have a voltage or temperature channel */
st->chan = chan;
at91_adc_cor(st, chan);
at91_adc_writel(st, CHER, BIT(chan->channel)); /* * TEMPMR.TEMPON needs to update after CHER otherwise if none * of the channels are enabled and TEMPMR.TEMPON = 1 will * trigger DRDY interruption while preparing for temperature read.
*/ if (chan->type == IIO_TEMP)
at91_adc_writel(st, TEMPMR, AT91_SAMA5D2_TEMPMR_TEMPON);
at91_adc_eoc_ena(st, chan->channel);
at91_adc_writel(st, CR, AT91_SAMA5D2_CR_START);
ret = wait_event_interruptible_timeout(st->wq_data_available,
st->conversion_done,
msecs_to_jiffies(1000)); if (ret == 0)
ret = -ETIMEDOUT;
if (ret > 0) {
*val = st->conversion_value;
ret = at91_adc_adjust_val_osr(st, val); if (chan->scan_type.sign == 's')
*val = sign_extend32(*val,
chan->scan_type.realbits - 1);
st->conversion_done = false;
}
staticint at91_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ struct at91_adc_state *st = iio_priv(indio_dev); int ret;
switch (mask) { case IIO_CHAN_INFO_RAW: if (!iio_device_claim_direct(indio_dev)) return -EBUSY;
ret = at91_adc_read_info_locked(indio_dev, chan, val);
iio_device_release_direct(indio_dev); return ret;
case IIO_CHAN_INFO_SCALE:
*val = st->vref_uv / 1000; if (chan->differential)
*val *= 2;
*val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_PROCESSED: if (chan->type != IIO_TEMP) return -EINVAL; if (!iio_device_claim_direct(indio_dev)) return -EBUSY;
ret = at91_adc_read_temp(indio_dev, chan, val);
iio_device_release_direct(indio_dev);
return ret;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = at91_adc_get_sample_freq(st); return IIO_VAL_INT;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*val = st->oversampling_ratio; return IIO_VAL_INT;
default: return -EINVAL;
}
}
staticint at91_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ struct at91_adc_state *st = iio_priv(indio_dev); int ret;
switch (mask) { case IIO_CHAN_INFO_OVERSAMPLING_RATIO: /* if no change, optimize out */ if (val == st->oversampling_ratio) return 0;
if (!iio_device_claim_direct(indio_dev)) return -EBUSY;
mutex_lock(&st->lock); /* update ratio */
ret = at91_adc_config_emr(st, val, 0);
mutex_unlock(&st->lock);
iio_device_release_direct(indio_dev); return ret; case IIO_CHAN_INFO_SAMP_FREQ: if (val < st->soc_info.min_sample_rate ||
val > st->soc_info.max_sample_rate) return -EINVAL;
staticvoid at91_adc_dma_init(struct at91_adc_state *st)
{ struct device *dev = &st->indio_dev->dev; struct dma_slave_config config = {0}; /* we have 2 bytes for each channel */ unsignedint sample_size = st->soc_info.platform->nr_channels * 2; /* * We make the buffer double the size of the fifo, * such that DMA uses one half of the buffer (full fifo size) * and the software uses the other half to read/write.
*/ unsignedint pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
sample_size * 2, PAGE_SIZE);
if (st->dma_st.dma_chan) return;
st->dma_st.dma_chan = dma_request_chan(dev, "rx"); if (IS_ERR(st->dma_st.dma_chan)) {
dev_info(dev, "can't get DMA channel\n");
st->dma_st.dma_chan = NULL; goto dma_exit;
}
if (val > AT91_HWFIFO_MAX_SIZE)
val = AT91_HWFIFO_MAX_SIZE;
if (!st->selected_trig->hw_trig) {
dev_dbg(&indio_dev->dev, "we need hw trigger for DMA\n"); return 0;
}
dev_dbg(&indio_dev->dev, "new watermark is %u\n", val);
st->dma_st.watermark = val;
/* * The logic here is: if we have watermark 1, it means we do * each conversion with it's own IRQ, thus we don't need DMA. * If the watermark is higher, we do DMA to do all the transfers in bulk
*/
if (val == 1)
at91_adc_dma_disable(st); elseif (val > 1)
at91_adc_dma_init(st);
/* * We can start the DMA only after setting the watermark and * having the DMA initialization completed
*/
ret = at91_adc_buffer_prepare(indio_dev); if (ret)
at91_adc_dma_disable(st);
if (bitmap_subset(scan_mask, &st->touch_st.channels_bitmask,
st->soc_info.platform->max_index + 1)) return 0; /* * if the new bitmap is a combination of touchscreen and regular * channels, then we are not fine
*/ if (bitmap_intersects(&st->touch_st.channels_bitmask, scan_mask,
st->soc_info.platform->max_index + 1)) return -EINVAL; return 0;
}
at91_adc_writel(st, CR, AT91_SAMA5D2_CR_SWRST); if (st->soc_info.platform->layout->EOC_IDR)
at91_adc_writel(st, EOC_IDR, 0xffffffff);
at91_adc_writel(st, IDR, 0xffffffff); /* * Transfer field must be set to 2 according to the datasheet and * allows different analog settings for each channel.
*/
at91_adc_writel(st, MR,
AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH);
if (!st->soc_info.platform->temp_sensor) return 0;
/* Get the calibration data from NVMEM. */
temp_calib = devm_nvmem_cell_get(dev, "temperature_calib"); if (IS_ERR(temp_calib)) {
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.