1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
4 */
5
6#include <linux/iio/iio.h>
7#include <linux/interrupt.h>
8#include <linux/io.h>
9#include <linux/mfd/core.h>
10#include <linux/mod_devicetable.h>
11#include <linux/module.h>
12#include <linux/property.h>
13
14#include "ssp.h"
15
16#define SSP_WDT_TIME			10000
17#define SSP_LIMIT_RESET_CNT		20
18#define SSP_LIMIT_TIMEOUT_CNT		3
19
20/* It is possible that it is max clk rate for version 1.0 of bootcode */
21#define SSP_BOOT_SPI_HZ	400000
22
23/*
24 * These fields can look enigmatic but this structure is used mainly to flat
25 * some values and depends on command type.
26 */
27struct ssp_instruction {
28	__le32 a;
29	__le32 b;
30	u8 c;
31} __attribute__((__packed__));
32
33static const u8 ssp_magnitude_table[] = {110, 85, 171, 71, 203, 195, 0, 67,
34	208, 56, 175, 244, 206, 213, 0, 92, 250, 0, 55, 48, 189, 252, 171,
35	243, 13, 45, 250};
36
37static const struct ssp_sensorhub_info ssp_rinato_info = {
38	.fw_name = "ssp_B2.fw",
39	.fw_crashed_name = "ssp_crashed.fw",
40	.fw_rev = 14052300,
41	.mag_table = ssp_magnitude_table,
42	.mag_length = ARRAY_SIZE(ssp_magnitude_table),
43};
44
45static const struct ssp_sensorhub_info ssp_thermostat_info = {
46	.fw_name = "thermostat_B2.fw",
47	.fw_crashed_name = "ssp_crashed.fw",
48	.fw_rev = 14080600,
49	.mag_table = ssp_magnitude_table,
50	.mag_length = ARRAY_SIZE(ssp_magnitude_table),
51};
52
53static const struct mfd_cell sensorhub_sensor_devs[] = {
54	{
55		.name = "ssp-accelerometer",
56	},
57	{
58		.name = "ssp-gyroscope",
59	},
60};
61
62static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
63{
64	gpiod_set_value(data->mcu_reset_gpiod, 0);
65	usleep_range(1000, 1200);
66	gpiod_set_value(data->mcu_reset_gpiod, 1);
67	msleep(50);
68}
69
70static void ssp_sync_available_sensors(struct ssp_data *data)
71{
72	int i, ret;
73
74	for (i = 0; i < SSP_SENSOR_MAX; ++i) {
75		if (data->available_sensors & BIT(i)) {
76			ret = ssp_enable_sensor(data, i, data->delay_buf[i]);
77			if (ret < 0) {
78				dev_err(&data->spi->dev,
79					"Sync sensor nr: %d fail\n", i);
80				continue;
81			}
82		}
83	}
84
85	ret = ssp_command(data, SSP_MSG2SSP_AP_MCU_SET_DUMPMODE,
86			  data->mcu_dump_mode);
87	if (ret < 0)
88		dev_err(&data->spi->dev,
89			"SSP_MSG2SSP_AP_MCU_SET_DUMPMODE failed\n");
90}
91
92static void ssp_enable_mcu(struct ssp_data *data, bool enable)
93{
94	dev_info(&data->spi->dev, "current shutdown = %d, old = %d\n", enable,
95		 data->shut_down);
96
97	if (enable && data->shut_down) {
98		data->shut_down = false;
99		enable_irq(data->spi->irq);
100		enable_irq_wake(data->spi->irq);
101	} else if (!enable && !data->shut_down) {
102		data->shut_down = true;
103		disable_irq(data->spi->irq);
104		disable_irq_wake(data->spi->irq);
105	} else {
106		dev_warn(&data->spi->dev, "current shutdown = %d, old = %d\n",
107			 enable, data->shut_down);
108	}
109}
110
111/*
112 * This function is the first one which communicates with the mcu so it is
113 * possible that the first attempt will fail
114 */
115static int ssp_check_fwbl(struct ssp_data *data)
116{
117	int retries = 0;
118
119	while (retries++ < 5) {
120		data->cur_firm_rev = ssp_get_firmware_rev(data);
121		if (data->cur_firm_rev == SSP_INVALID_REVISION ||
122		    data->cur_firm_rev == SSP_INVALID_REVISION2) {
123			dev_warn(&data->spi->dev,
124				 "Invalid revision, trying %d time\n", retries);
125		} else {
126			break;
127		}
128	}
129
130	if (data->cur_firm_rev == SSP_INVALID_REVISION ||
131	    data->cur_firm_rev == SSP_INVALID_REVISION2) {
132		dev_err(&data->spi->dev, "SSP_INVALID_REVISION\n");
133		return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
134	}
135
136	dev_info(&data->spi->dev,
137		 "MCU Firm Rev : Old = %8u, New = %8u\n",
138		 data->cur_firm_rev,
139		 data->sensorhub_info->fw_rev);
140
141	if (data->cur_firm_rev != data->sensorhub_info->fw_rev)
142		return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
143
144	return SSP_FW_DL_STATE_NONE;
145}
146
147static void ssp_reset_mcu(struct ssp_data *data)
148{
149	ssp_enable_mcu(data, false);
150	ssp_clean_pending_list(data);
151	ssp_toggle_mcu_reset_gpio(data);
152	ssp_enable_mcu(data, true);
153}
154
155static void ssp_wdt_work_func(struct work_struct *work)
156{
157	struct ssp_data *data = container_of(work, struct ssp_data, work_wdt);
158
159	dev_err(&data->spi->dev, "%s - Sensor state: 0x%x, RC: %u, CC: %u\n",
160		__func__, data->available_sensors, data->reset_cnt,
161		data->com_fail_cnt);
162
163	ssp_reset_mcu(data);
164	data->com_fail_cnt = 0;
165	data->timeout_cnt = 0;
166}
167
168static void ssp_wdt_timer_func(struct timer_list *t)
169{
170	struct ssp_data *data = from_timer(data, t, wdt_timer);
171
172	switch (data->fw_dl_state) {
173	case SSP_FW_DL_STATE_FAIL:
174	case SSP_FW_DL_STATE_DOWNLOADING:
175	case SSP_FW_DL_STATE_SYNC:
176		goto _mod;
177	}
178
179	if (data->timeout_cnt > SSP_LIMIT_TIMEOUT_CNT ||
180	    data->com_fail_cnt > SSP_LIMIT_RESET_CNT)
181		queue_work(system_power_efficient_wq, &data->work_wdt);
182_mod:
183	mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
184}
185
186static void ssp_enable_wdt_timer(struct ssp_data *data)
187{
188	mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
189}
190
191static void ssp_disable_wdt_timer(struct ssp_data *data)
192{
193	del_timer_sync(&data->wdt_timer);
194	cancel_work_sync(&data->work_wdt);
195}
196
197/**
198 * ssp_get_sensor_delay() - gets sensor data acquisition period
199 * @data:	sensorhub structure
200 * @type:	SSP sensor type
201 *
202 * Returns acquisition period in ms
203 */
204u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type)
205{
206	return data->delay_buf[type];
207}
208EXPORT_SYMBOL_NS(ssp_get_sensor_delay, IIO_SSP_SENSORS);
209
210/**
211 * ssp_enable_sensor() - enables data acquisition for sensor
212 * @data:	sensorhub structure
213 * @type:	SSP sensor type
214 * @delay:	delay in ms
215 *
216 * Returns 0 or negative value in case of error
217 */
218int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
219		      u32 delay)
220{
221	int ret;
222	struct ssp_instruction to_send;
223
224	to_send.a = cpu_to_le32(delay);
225	to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
226	to_send.c = data->batch_opt_buf[type];
227
228	switch (data->check_status[type]) {
229	case SSP_INITIALIZATION_STATE:
230		/* do calibration step, now just enable */
231	case SSP_ADD_SENSOR_STATE:
232		ret = ssp_send_instruction(data,
233					   SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD,
234					   type,
235					   (u8 *)&to_send, sizeof(to_send));
236		if (ret < 0) {
237			dev_err(&data->spi->dev, "Enabling sensor failed\n");
238			data->check_status[type] = SSP_NO_SENSOR_STATE;
239			goto derror;
240		}
241
242		data->sensor_enable |= BIT(type);
243		data->check_status[type] = SSP_RUNNING_SENSOR_STATE;
244		break;
245	case SSP_RUNNING_SENSOR_STATE:
246		ret = ssp_send_instruction(data,
247					   SSP_MSG2SSP_INST_CHANGE_DELAY, type,
248					   (u8 *)&to_send, sizeof(to_send));
249		if (ret < 0) {
250			dev_err(&data->spi->dev,
251				"Changing sensor delay failed\n");
252			goto derror;
253		}
254		break;
255	default:
256		data->check_status[type] = SSP_ADD_SENSOR_STATE;
257		break;
258	}
259
260	data->delay_buf[type] = delay;
261
262	if (atomic_inc_return(&data->enable_refcount) == 1)
263		ssp_enable_wdt_timer(data);
264
265	return 0;
266
267derror:
268	return ret;
269}
270EXPORT_SYMBOL_NS(ssp_enable_sensor, IIO_SSP_SENSORS);
271
272/**
273 * ssp_change_delay() - changes data acquisition for sensor
274 * @data:	sensorhub structure
275 * @type:	SSP sensor type
276 * @delay:	delay in ms
277 *
278 * Returns 0 or negative value in case of error
279 */
280int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
281		     u32 delay)
282{
283	int ret;
284	struct ssp_instruction to_send;
285
286	to_send.a = cpu_to_le32(delay);
287	to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
288	to_send.c = data->batch_opt_buf[type];
289
290	ret = ssp_send_instruction(data, SSP_MSG2SSP_INST_CHANGE_DELAY, type,
291				   (u8 *)&to_send, sizeof(to_send));
292	if (ret < 0) {
293		dev_err(&data->spi->dev, "Changing sensor delay failed\n");
294		return ret;
295	}
296
297	data->delay_buf[type] = delay;
298
299	return 0;
300}
301EXPORT_SYMBOL_NS(ssp_change_delay, IIO_SSP_SENSORS);
302
303/**
304 * ssp_disable_sensor() - disables sensor
305 *
306 * @data:	sensorhub structure
307 * @type:	SSP sensor type
308 *
309 * Returns 0 or negative value in case of error
310 */
311int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type)
312{
313	int ret;
314	__le32 command;
315
316	if (data->sensor_enable & BIT(type)) {
317		command = cpu_to_le32(data->delay_buf[type]);
318
319		ret = ssp_send_instruction(data,
320					   SSP_MSG2SSP_INST_BYPASS_SENSOR_RM,
321					   type, (u8 *)&command,
322					   sizeof(command));
323		if (ret < 0) {
324			dev_err(&data->spi->dev, "Remove sensor fail\n");
325			return ret;
326		}
327
328		data->sensor_enable &= ~BIT(type);
329	}
330
331	data->check_status[type] = SSP_ADD_SENSOR_STATE;
332
333	if (atomic_dec_and_test(&data->enable_refcount))
334		ssp_disable_wdt_timer(data);
335
336	return 0;
337}
338EXPORT_SYMBOL_NS(ssp_disable_sensor, IIO_SSP_SENSORS);
339
340static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id)
341{
342	struct ssp_data *data = dev_id;
343
344	/*
345	 * This wrapper is done to preserve error path for ssp_irq_msg, also
346	 * it is defined in different file.
347	 */
348	ssp_irq_msg(data);
349
350	return IRQ_HANDLED;
351}
352
353static int ssp_initialize_mcu(struct ssp_data *data)
354{
355	int ret;
356
357	ssp_clean_pending_list(data);
358
359	ret = ssp_get_chipid(data);
360	if (ret != SSP_DEVICE_ID) {
361		dev_err(&data->spi->dev, "%s - MCU %s ret = %d\n", __func__,
362			ret < 0 ? "is not working" : "identification failed",
363			ret);
364		return ret < 0 ? ret : -ENODEV;
365	}
366
367	dev_info(&data->spi->dev, "MCU device ID = %d\n", ret);
368
369	/*
370	 * needs clarification, for now do not want to export all transfer
371	 * methods to sensors' drivers
372	 */
373	ret = ssp_set_magnetic_matrix(data);
374	if (ret < 0) {
375		dev_err(&data->spi->dev,
376			"%s - ssp_set_magnetic_matrix failed\n", __func__);
377		return ret;
378	}
379
380	data->available_sensors = ssp_get_sensor_scanning_info(data);
381	if (data->available_sensors == 0) {
382		dev_err(&data->spi->dev,
383			"%s - ssp_get_sensor_scanning_info failed\n", __func__);
384		return -EIO;
385	}
386
387	data->cur_firm_rev = ssp_get_firmware_rev(data);
388	dev_info(&data->spi->dev, "MCU Firm Rev : New = %8u\n",
389		 data->cur_firm_rev);
390
391	return ssp_command(data, SSP_MSG2SSP_AP_MCU_DUMP_CHECK, 0);
392}
393
394/*
395 * sensorhub can request its reinitialization as some brutal and rare error
396 * handling. It can be requested from the MCU.
397 */
398static void ssp_refresh_task(struct work_struct *work)
399{
400	struct ssp_data *data = container_of((struct delayed_work *)work,
401					     struct ssp_data, work_refresh);
402
403	dev_info(&data->spi->dev, "refreshing\n");
404
405	data->reset_cnt++;
406
407	if (ssp_initialize_mcu(data) >= 0) {
408		ssp_sync_available_sensors(data);
409		if (data->last_ap_state != 0)
410			ssp_command(data, data->last_ap_state, 0);
411
412		if (data->last_resume_state != 0)
413			ssp_command(data, data->last_resume_state, 0);
414
415		data->timeout_cnt = 0;
416		data->com_fail_cnt = 0;
417	}
418}
419
420int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay)
421{
422	cancel_delayed_work_sync(&data->work_refresh);
423
424	return queue_delayed_work(system_power_efficient_wq,
425				  &data->work_refresh,
426				  msecs_to_jiffies(delay));
427}
428
429static const struct of_device_id ssp_of_match[] = {
430	{
431		.compatible	= "samsung,sensorhub-rinato",
432		.data		= &ssp_rinato_info,
433	}, {
434		.compatible	= "samsung,sensorhub-thermostat",
435		.data		= &ssp_thermostat_info,
436	},
437	{},
438};
439MODULE_DEVICE_TABLE(of, ssp_of_match);
440
441static struct ssp_data *ssp_parse_dt(struct device *dev)
442{
443	struct ssp_data *data;
444
445	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
446	if (!data)
447		return NULL;
448
449	data->mcu_ap_gpiod = devm_gpiod_get(dev, "mcu-ap", GPIOD_IN);
450	if (IS_ERR(data->mcu_ap_gpiod))
451		return NULL;
452
453	data->ap_mcu_gpiod = devm_gpiod_get(dev, "ap-mcu", GPIOD_OUT_HIGH);
454	if (IS_ERR(data->ap_mcu_gpiod))
455		return NULL;
456
457	data->mcu_reset_gpiod = devm_gpiod_get(dev, "mcu-reset",
458					       GPIOD_OUT_HIGH);
459	if (IS_ERR(data->mcu_reset_gpiod))
460		return NULL;
461
462	data->sensorhub_info = device_get_match_data(dev);
463
464	dev_set_drvdata(dev, data);
465
466	return data;
467}
468
469/**
470 * ssp_register_consumer() - registers iio consumer in ssp framework
471 *
472 * @indio_dev:	consumer iio device
473 * @type:	ssp sensor type
474 */
475void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type)
476{
477	struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
478
479	data->sensor_devs[type] = indio_dev;
480}
481EXPORT_SYMBOL_NS(ssp_register_consumer, IIO_SSP_SENSORS);
482
483static int ssp_probe(struct spi_device *spi)
484{
485	int ret, i;
486	struct ssp_data *data;
487
488	data = ssp_parse_dt(&spi->dev);
489	if (!data) {
490		dev_err(&spi->dev, "Failed to find platform data\n");
491		return -ENODEV;
492	}
493
494	ret = mfd_add_devices(&spi->dev, PLATFORM_DEVID_NONE,
495			      sensorhub_sensor_devs,
496			      ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL);
497	if (ret < 0) {
498		dev_err(&spi->dev, "mfd add devices fail\n");
499		return ret;
500	}
501
502	spi->mode = SPI_MODE_1;
503	ret = spi_setup(spi);
504	if (ret < 0) {
505		dev_err(&spi->dev, "Failed to setup spi\n");
506		return ret;
507	}
508
509	data->fw_dl_state = SSP_FW_DL_STATE_NONE;
510	data->spi = spi;
511	spi_set_drvdata(spi, data);
512
513	mutex_init(&data->comm_lock);
514
515	for (i = 0; i < SSP_SENSOR_MAX; ++i) {
516		data->delay_buf[i] = SSP_DEFAULT_POLLING_DELAY;
517		data->batch_latency_buf[i] = 0;
518		data->batch_opt_buf[i] = 0;
519		data->check_status[i] = SSP_INITIALIZATION_STATE;
520	}
521
522	data->delay_buf[SSP_BIO_HRM_LIB] = 100;
523
524	data->time_syncing = true;
525
526	mutex_init(&data->pending_lock);
527	INIT_LIST_HEAD(&data->pending_list);
528
529	atomic_set(&data->enable_refcount, 0);
530
531	INIT_WORK(&data->work_wdt, ssp_wdt_work_func);
532	INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task);
533
534	timer_setup(&data->wdt_timer, ssp_wdt_timer_func, 0);
535
536	ret = request_threaded_irq(data->spi->irq, NULL,
537				   ssp_irq_thread_fn,
538				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
539				   "SSP_Int", data);
540	if (ret < 0) {
541		dev_err(&spi->dev, "Irq request fail\n");
542		goto err_setup_irq;
543	}
544
545	/* Let's start with enabled one so irq balance could be ok */
546	data->shut_down = false;
547
548	/* just to avoid unbalanced irq set wake up */
549	enable_irq_wake(data->spi->irq);
550
551	data->fw_dl_state = ssp_check_fwbl(data);
552	if (data->fw_dl_state == SSP_FW_DL_STATE_NONE) {
553		ret = ssp_initialize_mcu(data);
554		if (ret < 0) {
555			dev_err(&spi->dev, "Initialize_mcu failed\n");
556			goto err_read_reg;
557		}
558	} else {
559		dev_err(&spi->dev, "Firmware version not supported\n");
560		ret = -EPERM;
561		goto err_read_reg;
562	}
563
564	return 0;
565
566err_read_reg:
567	free_irq(data->spi->irq, data);
568err_setup_irq:
569	mutex_destroy(&data->pending_lock);
570	mutex_destroy(&data->comm_lock);
571
572	dev_err(&spi->dev, "Probe failed!\n");
573
574	return ret;
575}
576
577static void ssp_remove(struct spi_device *spi)
578{
579	struct ssp_data *data = spi_get_drvdata(spi);
580
581	if (ssp_command(data, SSP_MSG2SSP_AP_STATUS_SHUTDOWN, 0) < 0)
582		dev_err(&data->spi->dev,
583			"SSP_MSG2SSP_AP_STATUS_SHUTDOWN failed\n");
584
585	ssp_enable_mcu(data, false);
586	ssp_disable_wdt_timer(data);
587
588	ssp_clean_pending_list(data);
589
590	free_irq(data->spi->irq, data);
591
592	del_timer_sync(&data->wdt_timer);
593	cancel_work_sync(&data->work_wdt);
594
595	mutex_destroy(&data->comm_lock);
596	mutex_destroy(&data->pending_lock);
597
598	mfd_remove_devices(&spi->dev);
599}
600
601static int ssp_suspend(struct device *dev)
602{
603	int ret;
604	struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
605
606	data->last_resume_state = SSP_MSG2SSP_AP_STATUS_SUSPEND;
607
608	if (atomic_read(&data->enable_refcount) > 0)
609		ssp_disable_wdt_timer(data);
610
611	ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_SUSPEND, 0);
612	if (ret < 0) {
613		dev_err(&data->spi->dev,
614			"%s SSP_MSG2SSP_AP_STATUS_SUSPEND failed\n", __func__);
615
616		ssp_enable_wdt_timer(data);
617		return ret;
618	}
619
620	data->time_syncing = false;
621	disable_irq(data->spi->irq);
622
623	return 0;
624}
625
626static int ssp_resume(struct device *dev)
627{
628	int ret;
629	struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
630
631	enable_irq(data->spi->irq);
632
633	if (atomic_read(&data->enable_refcount) > 0)
634		ssp_enable_wdt_timer(data);
635
636	ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_RESUME, 0);
637	if (ret < 0) {
638		dev_err(&data->spi->dev,
639			"%s SSP_MSG2SSP_AP_STATUS_RESUME failed\n", __func__);
640		ssp_disable_wdt_timer(data);
641		return ret;
642	}
643
644	/* timesyncing is set by MCU */
645	data->last_resume_state = SSP_MSG2SSP_AP_STATUS_RESUME;
646
647	return 0;
648}
649
650static DEFINE_SIMPLE_DEV_PM_OPS(ssp_pm_ops, ssp_suspend, ssp_resume);
651
652static struct spi_driver ssp_driver = {
653	.probe = ssp_probe,
654	.remove = ssp_remove,
655	.driver = {
656		.pm = pm_sleep_ptr(&ssp_pm_ops),
657		.of_match_table = ssp_of_match,
658		.name = "sensorhub"
659	},
660};
661
662module_spi_driver(ssp_driver);
663
664MODULE_DESCRIPTION("ssp sensorhub driver");
665MODULE_AUTHOR("Samsung Electronics");
666MODULE_LICENSE("GPL");
667