2017-10-26 01:48:07 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2017 Intel Corporation
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <adc.h>
|
|
|
|
#include <syscall_handler.h>
|
2018-05-18 04:38:16 +08:00
|
|
|
#include <string.h>
|
2017-10-26 01:48:07 +08:00
|
|
|
|
2018-05-05 06:57:57 +08:00
|
|
|
Z_SYSCALL_HANDLER(adc_enable, dev)
|
2018-04-05 04:50:32 +08:00
|
|
|
{
|
2018-05-05 06:57:57 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, enable));
|
2018-04-05 04:50:32 +08:00
|
|
|
_impl_adc_enable((struct device *)dev);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-05-05 06:57:57 +08:00
|
|
|
Z_SYSCALL_HANDLER(adc_disable, dev)
|
2018-04-05 04:50:32 +08:00
|
|
|
{
|
2018-05-05 06:57:57 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, disable));
|
2018-04-05 04:50:32 +08:00
|
|
|
_impl_adc_disable((struct device *)dev);
|
|
|
|
return 0;
|
|
|
|
}
|
2017-10-26 01:48:07 +08:00
|
|
|
|
2018-05-05 06:57:57 +08:00
|
|
|
Z_SYSCALL_HANDLER(adc_read, dev, seq_table_p)
|
2017-10-26 01:48:07 +08:00
|
|
|
{
|
2018-05-18 04:38:16 +08:00
|
|
|
struct adc_seq_entry *entry, *entries_copy;
|
2017-10-26 01:48:07 +08:00
|
|
|
struct adc_seq_table *seq_table = (struct adc_seq_table *)seq_table_p;
|
2018-05-18 04:38:16 +08:00
|
|
|
struct adc_seq_table seq_table_copy;
|
|
|
|
unsigned int entries_bounds;
|
|
|
|
int i = 0, ret;
|
2017-10-26 01:48:07 +08:00
|
|
|
|
2018-05-05 06:57:57 +08:00
|
|
|
Z_OOPS(Z_SYSCALL_DRIVER_ADC(dev, read));
|
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_READ(seq_table, sizeof(struct adc_seq_table)));
|
2017-10-26 01:48:07 +08:00
|
|
|
|
2018-05-18 04:38:16 +08:00
|
|
|
seq_table_copy = *seq_table;
|
|
|
|
if (Z_SYSCALL_VERIFY_MSG(
|
|
|
|
!__builtin_umul_overflow(seq_table_copy.num_entries,
|
|
|
|
sizeof(struct adc_seq_entry),
|
|
|
|
&entries_bounds),
|
|
|
|
"num_entries too large")) {
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
Z_OOPS(Z_SYSCALL_MEMORY_READ(seq_table_copy.entries, entries_bounds));
|
|
|
|
entries_copy = z_thread_malloc(entries_bounds);
|
|
|
|
if (!entries_copy) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(entries_copy, seq_table_copy.entries, entries_bounds);
|
|
|
|
seq_table_copy.entries = entries_copy;
|
|
|
|
|
|
|
|
for (entry = seq_table_copy.entries; i < seq_table_copy.num_entries;
|
2017-10-26 01:48:07 +08:00
|
|
|
i++, entry++) {
|
2018-05-18 04:38:16 +08:00
|
|
|
if (Z_SYSCALL_MEMORY_WRITE(entry->buffer,
|
|
|
|
entry->buffer_length)) {
|
|
|
|
k_free(entries_copy);
|
|
|
|
Z_OOPS(1);
|
|
|
|
}
|
2017-10-26 01:48:07 +08:00
|
|
|
}
|
|
|
|
|
2018-05-18 04:38:16 +08:00
|
|
|
ret = _impl_adc_read((struct device *)dev, &seq_table_copy);
|
|
|
|
k_free(entries_copy);
|
|
|
|
out:
|
|
|
|
return ret;
|
2017-10-26 01:48:07 +08:00
|
|
|
}
|