1 /*
2  * Copyright (c) 2020 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "dummy_sensor.h"
8 #include <zephyr/drivers/sensor.h>
9 #include <zephyr/device.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/ztest.h>
12 
13 LOG_MODULE_REGISTER(dummy_sensor, LOG_LEVEL_DBG);
14 static struct dummy_sensor_data dummy_data;
15 /**
16  * @brief config bus address at compile time
17  */
18 static const struct dummy_sensor_config dummy_config = {
19 	.i2c_name = "dummy I2C",
20 	.i2c_address = 123
21 };
22 
dummy_sensor_sample_fetch(const struct device * dev,enum sensor_channel chan)23 static int dummy_sensor_sample_fetch(const struct device *dev,
24 				     enum sensor_channel chan)
25 {
26 	ARG_UNUSED(dev);
27 	ARG_UNUSED(chan);
28 
29 	/* Just return success due to dummy sensor driver here. */
30 	return 0;
31 }
32 
dummy_sensor_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)33 static int dummy_sensor_channel_get(const struct device *dev,
34 				    enum sensor_channel chan,
35 				    struct sensor_value *val)
36 {
37 	struct dummy_sensor_data *data = dev->data;
38 
39 	switch (chan) {
40 	case SENSOR_CHAN_LIGHT:
41 		val->val1 = data->val[0].val1;
42 		val->val2 = data->val[0].val2;
43 		break;
44 	case SENSOR_CHAN_RED:
45 		val->val1 = data->val[1].val1;
46 		val->val2 = data->val[1].val2;
47 		break;
48 	case SENSOR_CHAN_GREEN:
49 		val->val1 = data->val[2].val1;
50 		val->val2 = data->val[2].val2;
51 		break;
52 	case SENSOR_CHAN_BLUE:
53 		val->val1 = data->val[3].val1;
54 		val->val2 = data->val[3].val2;
55 		break;
56 	case SENSOR_CHAN_PROX:
57 		val->val1 = data->val[4].val1;
58 		val->val2 = data->val[4].val2;
59 		break;
60 	default:
61 		return -ENOTSUP;
62 	}
63 
64 	return 0;
65 }
66 
67 /* return 0 for dummy driver to imitate interrupt */
dummy_init_interrupt(const struct device * dev)68 static int dummy_init_interrupt(const struct device *dev)
69 {
70 	ARG_UNUSED(dev);
71 
72 	return 0;
73 }
74 
dummy_sensor_init(const struct device * dev)75 static int dummy_sensor_init(const struct device *dev)
76 {
77 	struct dummy_sensor_data *data = dev->data;
78 	const struct dummy_sensor_config *config = dev->config;
79 	/* i2c should be null for dummy driver */
80 	const struct device *i2c = device_get_binding(config->i2c_name);
81 
82 	/* Bus and address should be configured. */
83 	zassert_str_equal(config->i2c_name, "dummy I2C");
84 	zassert_equal(config->i2c_address, 123);
85 
86 	if (i2c != NULL) {
87 		LOG_ERR("Should be Null for %s device!", config->i2c_name);
88 		return -1;
89 	}
90 
91 	if (dummy_init_interrupt(dev) < 0) {
92 		LOG_ERR("Failed to initialize interrupt!");
93 		return -1;
94 	}
95 
96 	/* initialize the channels value for dummy driver */
97 	for (int i = 0; i < SENSOR_CHANNEL_NUM; i++) {
98 		data->val[i].val1 = i;
99 		data->val[i].val2 = i*i;
100 	}
101 
102 	return 0;
103 }
104 
dummy_sensor_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)105 int dummy_sensor_attr_set(const struct device *dev,
106 			  enum sensor_channel chan,
107 			  enum sensor_attribute attr,
108 			  const struct sensor_value *val)
109 {
110 	struct dummy_sensor_data *data = dev->data;
111 
112 	if (chan == SENSOR_CHAN_PROX &&
113 	    attr == SENSOR_ATTR_UPPER_THRESH) {
114 		data->val[4].val1 = val->val1;
115 		data->val[4].val2 = val->val2;
116 		return 0;
117 	}
118 
119 	return -ENOTSUP;
120 }
121 
dummy_sensor_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)122 int dummy_sensor_attr_get(const struct device *dev,
123 			  enum sensor_channel chan,
124 			  enum sensor_attribute attr,
125 			  struct sensor_value *val)
126 {
127 	struct dummy_sensor_data *data = dev->data;
128 
129 	if (chan == SENSOR_CHAN_PROX &&
130 	    attr == SENSOR_ATTR_UPPER_THRESH) {
131 		val->val1 = data->val[4].val1;
132 		val->val2 = data->val[4].val2;
133 		return 0;
134 	}
135 
136 	return -ENOTSUP;
137 }
138 
dummy_sensor_trigger_set(const struct device * dev,const struct sensor_trigger * trig,sensor_trigger_handler_t handler)139 int dummy_sensor_trigger_set(const struct device *dev,
140 			     const struct sensor_trigger *trig,
141 			     sensor_trigger_handler_t handler)
142 {
143 	struct dummy_sensor_data *data = dev->data;
144 
145 	switch (trig->type) {
146 	case SENSOR_TRIG_THRESHOLD:
147 	case SENSOR_TRIG_TIMER:
148 	case SENSOR_TRIG_DATA_READY:
149 	case SENSOR_TRIG_DELTA:
150 	case SENSOR_TRIG_NEAR_FAR:
151 		/* Use the same action to dummy above triggers */
152 		if (handler != NULL) {
153 			data->handler = handler;
154 			data->handler(dev, NULL);
155 		}
156 		break;
157 	default:
158 		return -ENOTSUP;
159 	}
160 
161 	return 0;
162 }
163 
164 static DEVICE_API(sensor, dummy_sensor_api) = {
165 	.sample_fetch = &dummy_sensor_sample_fetch,
166 	.channel_get = &dummy_sensor_channel_get,
167 	.attr_set = dummy_sensor_attr_set,
168 	.attr_get = dummy_sensor_attr_get,
169 	.trigger_set = dummy_sensor_trigger_set,
170 };
171 
172 static DEVICE_API(sensor, dummy_sensor_no_trig_api) = {
173 	.sample_fetch = &dummy_sensor_sample_fetch,
174 	.channel_get = &dummy_sensor_channel_get,
175 	.attr_set = NULL,
176 	.attr_get = NULL,
177 	.trigger_set = NULL,
178 };
179 
180 DEVICE_DEFINE(dummy_sensor, DUMMY_SENSOR_NAME, &dummy_sensor_init,
181 		    NULL, &dummy_data, &dummy_config, POST_KERNEL,
182 		    CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &dummy_sensor_api);
183 
184 DEVICE_DEFINE(dummy_sensor_no_trig, DUMMY_SENSOR_NAME_NO_TRIG, &dummy_sensor_init,
185 		    NULL, &dummy_data, &dummy_config, POST_KERNEL,
186 		    CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &dummy_sensor_no_trig_api);
187