| /* |
| * Copyright (c) 2019 Intel Corporation. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include "sample_driver.h" |
| #include <string.h> |
| #include <zephyr/kernel.h> |
| #include <zephyr/logging/log.h> |
| |
| LOG_MODULE_REGISTER(sample_driver); |
| |
| /* |
| * Fake sample driver for demonstration purposes |
| * |
| * This is fake driver for demonstration purposes, showing how an application |
| * can make system calls to interact with it. |
| * |
| * The driver sets up a timer which is used to fake interrupts. |
| */ |
| |
| struct sample_driver_foo_dev_data { |
| const struct device *dev; |
| sample_driver_callback_t cb; |
| void *cb_context; |
| struct k_timer timer; /* to fake 'interrupts' */ |
| uint32_t count; |
| }; |
| |
| static int sample_driver_foo_write(const struct device *dev, void *buf) |
| { |
| LOG_DBG("%s(%p, %p)", __func__, dev, buf); |
| |
| return 0; |
| } |
| |
| static int sample_driver_foo_set_callback(const struct device *dev, |
| sample_driver_callback_t cb, |
| void *context) |
| { |
| struct sample_driver_foo_dev_data *data = dev->data; |
| unsigned int key = irq_lock(); |
| |
| data->cb_context = context; |
| data->cb = cb; |
| irq_unlock(key); |
| |
| return 0; |
| } |
| |
| static int sample_driver_foo_state_set(const struct device *dev, bool active) |
| { |
| struct sample_driver_foo_dev_data *data = dev->data; |
| |
| LOG_DBG("%s(%p, %d)", __func__, dev, active); |
| |
| data->timer.user_data = data; |
| if (active) { |
| k_timer_start(&data->timer, K_MSEC(100), K_MSEC(100)); |
| } else { |
| k_timer_stop(&data->timer); |
| } |
| |
| return 0; |
| } |
| |
| static struct sample_driver_api sample_driver_foo_api = { |
| .write = sample_driver_foo_write, |
| .set_callback = sample_driver_foo_set_callback, |
| .state_set = sample_driver_foo_state_set |
| }; |
| |
| static void sample_driver_foo_isr(void *param) |
| { |
| struct sample_driver_foo_dev_data *data = param; |
| |
| char data_payload[SAMPLE_DRIVER_MSG_SIZE]; |
| |
| LOG_INF("%s: param=%p count=%u", __func__, param, |
| data->count); |
| |
| /* Just for demonstration purposes; the data payload is full of junk */ |
| if (data->cb) { |
| data->cb(data->dev, data->cb_context, data_payload); |
| } |
| |
| data->count++; |
| } |
| |
| static void sample_driver_timer_cb(struct k_timer *timer) |
| { |
| sample_driver_foo_isr(timer->user_data); |
| } |
| |
| static int sample_driver_foo_init(const struct device *dev) |
| { |
| struct sample_driver_foo_dev_data *data = dev->data; |
| |
| k_timer_init(&data->timer, sample_driver_timer_cb, NULL); |
| |
| LOG_DBG("initialized foo sample driver %p", dev); |
| |
| data->dev = dev; |
| |
| return 0; |
| } |
| |
| static struct sample_driver_foo_dev_data sample_driver_foo_dev_data_0; |
| |
| DEVICE_DEFINE(sample_driver_foo_0, SAMPLE_DRIVER_NAME_0, |
| &sample_driver_foo_init, NULL, |
| &sample_driver_foo_dev_data_0, NULL, |
| POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, |
| &sample_driver_foo_api); |