1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2020 Invensense, Inc.
4  */
5 
6 #include <linux/kernel.h>
7 #include <linux/device.h>
8 #include <linux/mutex.h>
9 #include <linux/pm_runtime.h>
10 #include <linux/regmap.h>
11 #include <linux/delay.h>
12 #include <linux/iio/iio.h>
13 #include <linux/iio/buffer.h>
14 
15 #include "inv_icm42600.h"
16 #include "inv_icm42600_timestamp.h"
17 #include "inv_icm42600_buffer.h"
18 
19 /* FIFO header: 1 byte */
20 #define INV_ICM42600_FIFO_HEADER_MSG		BIT(7)
21 #define INV_ICM42600_FIFO_HEADER_ACCEL		BIT(6)
22 #define INV_ICM42600_FIFO_HEADER_GYRO		BIT(5)
23 #define INV_ICM42600_FIFO_HEADER_TMST_FSYNC	GENMASK(3, 2)
24 #define INV_ICM42600_FIFO_HEADER_ODR_ACCEL	BIT(1)
25 #define INV_ICM42600_FIFO_HEADER_ODR_GYRO	BIT(0)
26 
27 struct inv_icm42600_fifo_1sensor_packet {
28 	uint8_t header;
29 	struct inv_icm42600_fifo_sensor_data data;
30 	int8_t temp;
31 } __packed;
32 #define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE		8
33 
34 struct inv_icm42600_fifo_2sensors_packet {
35 	uint8_t header;
36 	struct inv_icm42600_fifo_sensor_data accel;
37 	struct inv_icm42600_fifo_sensor_data gyro;
38 	int8_t temp;
39 	__be16 timestamp;
40 } __packed;
41 #define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE		16
42 
43 ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
44 					const void **gyro, const int8_t **temp,
45 					const void **timestamp, unsigned int *odr)
46 {
47 	const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet;
48 	const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet;
49 	uint8_t header = *((const uint8_t *)packet);
50 
51 	/* FIFO empty */
52 	if (header & INV_ICM42600_FIFO_HEADER_MSG) {
53 		*accel = NULL;
54 		*gyro = NULL;
55 		*temp = NULL;
56 		*timestamp = NULL;
57 		*odr = 0;
58 		return 0;
59 	}
60 
61 	/* handle odr flags */
62 	*odr = 0;
63 	if (header & INV_ICM42600_FIFO_HEADER_ODR_GYRO)
64 		*odr |= INV_ICM42600_SENSOR_GYRO;
65 	if (header & INV_ICM42600_FIFO_HEADER_ODR_ACCEL)
66 		*odr |= INV_ICM42600_SENSOR_ACCEL;
67 
68 	/* accel + gyro */
69 	if ((header & INV_ICM42600_FIFO_HEADER_ACCEL) &&
70 	    (header & INV_ICM42600_FIFO_HEADER_GYRO)) {
71 		*accel = &pack2->accel;
72 		*gyro = &pack2->gyro;
73 		*temp = &pack2->temp;
74 		*timestamp = &pack2->timestamp;
75 		return INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE;
76 	}
77 
78 	/* accel only */
79 	if (header & INV_ICM42600_FIFO_HEADER_ACCEL) {
80 		*accel = &pack1->data;
81 		*gyro = NULL;
82 		*temp = &pack1->temp;
83 		*timestamp = NULL;
84 		return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
85 	}
86 
87 	/* gyro only */
88 	if (header & INV_ICM42600_FIFO_HEADER_GYRO) {
89 		*accel = NULL;
90 		*gyro = &pack1->data;
91 		*temp = &pack1->temp;
92 		*timestamp = NULL;
93 		return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
94 	}
95 
96 	/* invalid packet if here */
97 	return -EINVAL;
98 }
99 
100 void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st)
101 {
102 	uint32_t period_gyro, period_accel, period;
103 
104 	if (st->fifo.en & INV_ICM42600_SENSOR_GYRO)
105 		period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr);
106 	else
107 		period_gyro = U32_MAX;
108 
109 	if (st->fifo.en & INV_ICM42600_SENSOR_ACCEL)
110 		period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr);
111 	else
112 		period_accel = U32_MAX;
113 
114 	if (period_gyro <= period_accel)
115 		period = period_gyro;
116 	else
117 		period = period_accel;
118 
119 	st->fifo.period = period;
120 }
121 
122 int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st,
123 				    unsigned int fifo_en)
124 {
125 	unsigned int mask, val;
126 	int ret;
127 
128 	/* update only FIFO EN bits */
129 	mask = INV_ICM42600_FIFO_CONFIG1_TMST_FSYNC_EN |
130 		INV_ICM42600_FIFO_CONFIG1_TEMP_EN |
131 		INV_ICM42600_FIFO_CONFIG1_GYRO_EN |
132 		INV_ICM42600_FIFO_CONFIG1_ACCEL_EN;
133 
134 	val = 0;
135 	if (fifo_en & INV_ICM42600_SENSOR_GYRO)
136 		val |= INV_ICM42600_FIFO_CONFIG1_GYRO_EN;
137 	if (fifo_en & INV_ICM42600_SENSOR_ACCEL)
138 		val |= INV_ICM42600_FIFO_CONFIG1_ACCEL_EN;
139 	if (fifo_en & INV_ICM42600_SENSOR_TEMP)
140 		val |= INV_ICM42600_FIFO_CONFIG1_TEMP_EN;
141 
142 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, mask, val);
143 	if (ret)
144 		return ret;
145 
146 	st->fifo.en = fifo_en;
147 	inv_icm42600_buffer_update_fifo_period(st);
148 
149 	return 0;
150 }
151 
152 static size_t inv_icm42600_get_packet_size(unsigned int fifo_en)
153 {
154 	size_t packet_size;
155 
156 	if ((fifo_en & INV_ICM42600_SENSOR_GYRO) &&
157 	    (fifo_en & INV_ICM42600_SENSOR_ACCEL))
158 		packet_size = INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE;
159 	else
160 		packet_size = INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
161 
162 	return packet_size;
163 }
164 
165 static unsigned int inv_icm42600_wm_truncate(unsigned int watermark,
166 					     size_t packet_size)
167 {
168 	size_t wm_size;
169 	unsigned int wm;
170 
171 	wm_size = watermark * packet_size;
172 	if (wm_size > INV_ICM42600_FIFO_WATERMARK_MAX)
173 		wm_size = INV_ICM42600_FIFO_WATERMARK_MAX;
174 
175 	wm = wm_size / packet_size;
176 
177 	return wm;
178 }
179 
180 /**
181  * inv_icm42600_buffer_update_watermark - update watermark FIFO threshold
182  * @st:	driver internal state
183  *
184  * Returns 0 on success, a negative error code otherwise.
185  *
186  * FIFO watermark threshold is computed based on the required watermark values
187  * set for gyro and accel sensors. Since watermark is all about acceptable data
188  * latency, use the smallest setting between the 2. It means choosing the
189  * smallest latency but this is not as simple as choosing the smallest watermark
190  * value. Latency depends on watermark and ODR. It requires several steps:
191  * 1) compute gyro and accel latencies and choose the smallest value.
192  * 2) adapt the choosen latency so that it is a multiple of both gyro and accel
193  *    ones. Otherwise it is possible that you don't meet a requirement. (for
194  *    example with gyro @100Hz wm 4 and accel @100Hz with wm 6, choosing the
195  *    value of 4 will not meet accel latency requirement because 6 is not a
196  *    multiple of 4. You need to use the value 2.)
197  * 3) Since all periods are multiple of each others, watermark is computed by
198  *    dividing this computed latency by the smallest period, which corresponds
199  *    to the FIFO frequency. Beware that this is only true because we are not
200  *    using 500Hz frequency which is not a multiple of the others.
201  */
202 int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st)
203 {
204 	size_t packet_size, wm_size;
205 	unsigned int wm_gyro, wm_accel, watermark;
206 	uint32_t period_gyro, period_accel, period;
207 	uint32_t latency_gyro, latency_accel, latency;
208 	bool restore;
209 	__le16 raw_wm;
210 	int ret;
211 
212 	packet_size = inv_icm42600_get_packet_size(st->fifo.en);
213 
214 	/* compute sensors latency, depending on sensor watermark and odr */
215 	wm_gyro = inv_icm42600_wm_truncate(st->fifo.watermark.gyro, packet_size);
216 	wm_accel = inv_icm42600_wm_truncate(st->fifo.watermark.accel, packet_size);
217 	/* use us for odr to avoid overflow using 32 bits values */
218 	period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr) / 1000UL;
219 	period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr) / 1000UL;
220 	latency_gyro = period_gyro * wm_gyro;
221 	latency_accel = period_accel * wm_accel;
222 
223 	/* 0 value for watermark means that the sensor is turned off */
224 	if (latency_gyro == 0) {
225 		watermark = wm_accel;
226 	} else if (latency_accel == 0) {
227 		watermark = wm_gyro;
228 	} else {
229 		/* compute the smallest latency that is a multiple of both */
230 		if (latency_gyro <= latency_accel)
231 			latency = latency_gyro - (latency_accel % latency_gyro);
232 		else
233 			latency = latency_accel - (latency_gyro % latency_accel);
234 		/* use the shortest period */
235 		if (period_gyro <= period_accel)
236 			period = period_gyro;
237 		else
238 			period = period_accel;
239 		/* all this works because periods are multiple of each others */
240 		watermark = latency / period;
241 		if (watermark < 1)
242 			watermark = 1;
243 	}
244 
245 	/* compute watermark value in bytes */
246 	wm_size = watermark * packet_size;
247 
248 	/* changing FIFO watermark requires to turn off watermark interrupt */
249 	ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
250 				       INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN,
251 				       0, &restore);
252 	if (ret)
253 		return ret;
254 
255 	raw_wm = INV_ICM42600_FIFO_WATERMARK_VAL(wm_size);
256 	memcpy(st->buffer, &raw_wm, sizeof(raw_wm));
257 	ret = regmap_bulk_write(st->map, INV_ICM42600_REG_FIFO_WATERMARK,
258 				st->buffer, sizeof(raw_wm));
259 	if (ret)
260 		return ret;
261 
262 	/* restore watermark interrupt */
263 	if (restore) {
264 		ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
265 					 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN,
266 					 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN);
267 		if (ret)
268 			return ret;
269 	}
270 
271 	return 0;
272 }
273 
274 static int inv_icm42600_buffer_preenable(struct iio_dev *indio_dev)
275 {
276 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
277 	struct device *dev = regmap_get_device(st->map);
278 	struct inv_icm42600_timestamp *ts = iio_priv(indio_dev);
279 
280 	pm_runtime_get_sync(dev);
281 
282 	mutex_lock(&st->lock);
283 	inv_icm42600_timestamp_reset(ts);
284 	mutex_unlock(&st->lock);
285 
286 	return 0;
287 }
288 
289 /*
290  * update_scan_mode callback is turning sensors on and setting data FIFO enable
291  * bits.
292  */
293 static int inv_icm42600_buffer_postenable(struct iio_dev *indio_dev)
294 {
295 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
296 	int ret;
297 
298 	mutex_lock(&st->lock);
299 
300 	/* exit if FIFO is already on */
301 	if (st->fifo.on) {
302 		ret = 0;
303 		goto out_on;
304 	}
305 
306 	/* set FIFO threshold interrupt */
307 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
308 				 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN,
309 				 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN);
310 	if (ret)
311 		goto out_unlock;
312 
313 	/* flush FIFO data */
314 	ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET,
315 			   INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH);
316 	if (ret)
317 		goto out_unlock;
318 
319 	/* set FIFO in streaming mode */
320 	ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
321 			   INV_ICM42600_FIFO_CONFIG_STREAM);
322 	if (ret)
323 		goto out_unlock;
324 
325 	/* workaround: first read of FIFO count after reset is always 0 */
326 	ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, st->buffer, 2);
327 	if (ret)
328 		goto out_unlock;
329 
330 out_on:
331 	/* increase FIFO on counter */
332 	st->fifo.on++;
333 out_unlock:
334 	mutex_unlock(&st->lock);
335 	return ret;
336 }
337 
338 static int inv_icm42600_buffer_predisable(struct iio_dev *indio_dev)
339 {
340 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
341 	int ret;
342 
343 	mutex_lock(&st->lock);
344 
345 	/* exit if there are several sensors using the FIFO */
346 	if (st->fifo.on > 1) {
347 		ret = 0;
348 		goto out_off;
349 	}
350 
351 	/* set FIFO in bypass mode */
352 	ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
353 			   INV_ICM42600_FIFO_CONFIG_BYPASS);
354 	if (ret)
355 		goto out_unlock;
356 
357 	/* flush FIFO data */
358 	ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET,
359 			   INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH);
360 	if (ret)
361 		goto out_unlock;
362 
363 	/* disable FIFO threshold interrupt */
364 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0,
365 				 INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN, 0);
366 	if (ret)
367 		goto out_unlock;
368 
369 out_off:
370 	/* decrease FIFO on counter */
371 	st->fifo.on--;
372 out_unlock:
373 	mutex_unlock(&st->lock);
374 	return ret;
375 }
376 
377 static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev)
378 {
379 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
380 	struct device *dev = regmap_get_device(st->map);
381 	unsigned int sensor;
382 	unsigned int *watermark;
383 	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
384 	unsigned int sleep_temp = 0;
385 	unsigned int sleep_sensor = 0;
386 	unsigned int sleep;
387 	int ret;
388 
389 	if (indio_dev == st->indio_gyro) {
390 		sensor = INV_ICM42600_SENSOR_GYRO;
391 		watermark = &st->fifo.watermark.gyro;
392 	} else if (indio_dev == st->indio_accel) {
393 		sensor = INV_ICM42600_SENSOR_ACCEL;
394 		watermark = &st->fifo.watermark.accel;
395 	} else {
396 		return -EINVAL;
397 	}
398 
399 	mutex_lock(&st->lock);
400 
401 	ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor);
402 	if (ret)
403 		goto out_unlock;
404 
405 	*watermark = 0;
406 	ret = inv_icm42600_buffer_update_watermark(st);
407 	if (ret)
408 		goto out_unlock;
409 
410 	conf.mode = INV_ICM42600_SENSOR_MODE_OFF;
411 	if (sensor == INV_ICM42600_SENSOR_GYRO)
412 		ret = inv_icm42600_set_gyro_conf(st, &conf, &sleep_sensor);
413 	else
414 		ret = inv_icm42600_set_accel_conf(st, &conf, &sleep_sensor);
415 	if (ret)
416 		goto out_unlock;
417 
418 	/* if FIFO is off, turn temperature off */
419 	if (!st->fifo.on)
420 		ret = inv_icm42600_set_temp_conf(st, false, &sleep_temp);
421 
422 out_unlock:
423 	mutex_unlock(&st->lock);
424 
425 	/* sleep maximum required time */
426 	if (sleep_sensor > sleep_temp)
427 		sleep = sleep_sensor;
428 	else
429 		sleep = sleep_temp;
430 	if (sleep)
431 		msleep(sleep);
432 
433 	pm_runtime_mark_last_busy(dev);
434 	pm_runtime_put_autosuspend(dev);
435 
436 	return ret;
437 }
438 
439 const struct iio_buffer_setup_ops inv_icm42600_buffer_ops = {
440 	.preenable = inv_icm42600_buffer_preenable,
441 	.postenable = inv_icm42600_buffer_postenable,
442 	.predisable = inv_icm42600_buffer_predisable,
443 	.postdisable = inv_icm42600_buffer_postdisable,
444 };
445 
446 int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
447 				  unsigned int max)
448 {
449 	size_t max_count;
450 	__be16 *raw_fifo_count;
451 	ssize_t i, size;
452 	const void *accel, *gyro, *timestamp;
453 	const int8_t *temp;
454 	unsigned int odr;
455 	int ret;
456 
457 	/* reset all samples counters */
458 	st->fifo.count = 0;
459 	st->fifo.nb.gyro = 0;
460 	st->fifo.nb.accel = 0;
461 	st->fifo.nb.total = 0;
462 
463 	/* compute maximum FIFO read size */
464 	if (max == 0)
465 		max_count = sizeof(st->fifo.data);
466 	else
467 		max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
468 
469 	/* read FIFO count value */
470 	raw_fifo_count = (__be16 *)st->buffer;
471 	ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT,
472 			       raw_fifo_count, sizeof(*raw_fifo_count));
473 	if (ret)
474 		return ret;
475 	st->fifo.count = be16_to_cpup(raw_fifo_count);
476 
477 	/* check and clamp FIFO count value */
478 	if (st->fifo.count == 0)
479 		return 0;
480 	if (st->fifo.count > max_count)
481 		st->fifo.count = max_count;
482 
483 	/* read all FIFO data in internal buffer */
484 	ret = regmap_noinc_read(st->map, INV_ICM42600_REG_FIFO_DATA,
485 				st->fifo.data, st->fifo.count);
486 	if (ret)
487 		return ret;
488 
489 	/* compute number of samples for each sensor */
490 	for (i = 0; i < st->fifo.count; i += size) {
491 		size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i],
492 				&accel, &gyro, &temp, &timestamp, &odr);
493 		if (size <= 0)
494 			break;
495 		if (gyro != NULL && inv_icm42600_fifo_is_data_valid(gyro))
496 			st->fifo.nb.gyro++;
497 		if (accel != NULL && inv_icm42600_fifo_is_data_valid(accel))
498 			st->fifo.nb.accel++;
499 		st->fifo.nb.total++;
500 	}
501 
502 	return 0;
503 }
504 
505 int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st)
506 {
507 	struct inv_icm42600_timestamp *ts;
508 	int ret;
509 
510 	if (st->fifo.nb.total == 0)
511 		return 0;
512 
513 	/* handle gyroscope timestamp and FIFO data parsing */
514 	ts = iio_priv(st->indio_gyro);
515 	inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
516 					 st->fifo.nb.gyro, st->timestamp.gyro);
517 	if (st->fifo.nb.gyro > 0) {
518 		ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
519 		if (ret)
520 			return ret;
521 	}
522 
523 	/* handle accelerometer timestamp and FIFO data parsing */
524 	ts = iio_priv(st->indio_accel);
525 	inv_icm42600_timestamp_interrupt(ts, st->fifo.period, st->fifo.nb.total,
526 					 st->fifo.nb.accel, st->timestamp.accel);
527 	if (st->fifo.nb.accel > 0) {
528 		ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
529 		if (ret)
530 			return ret;
531 	}
532 
533 	return 0;
534 }
535 
536 int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
537 				     unsigned int count)
538 {
539 	struct inv_icm42600_timestamp *ts;
540 	int64_t gyro_ts, accel_ts;
541 	int ret;
542 
543 	gyro_ts = iio_get_time_ns(st->indio_gyro);
544 	accel_ts = iio_get_time_ns(st->indio_accel);
545 
546 	ret = inv_icm42600_buffer_fifo_read(st, count);
547 	if (ret)
548 		return ret;
549 
550 	if (st->fifo.nb.total == 0)
551 		return 0;
552 
553 	if (st->fifo.nb.gyro > 0) {
554 		ts = iio_priv(st->indio_gyro);
555 		inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
556 						 st->fifo.nb.total, st->fifo.nb.gyro,
557 						 gyro_ts);
558 		ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro);
559 		if (ret)
560 			return ret;
561 	}
562 
563 	if (st->fifo.nb.accel > 0) {
564 		ts = iio_priv(st->indio_accel);
565 		inv_icm42600_timestamp_interrupt(ts, st->fifo.period,
566 						 st->fifo.nb.total, st->fifo.nb.accel,
567 						 accel_ts);
568 		ret = inv_icm42600_accel_parse_fifo(st->indio_accel);
569 		if (ret)
570 			return ret;
571 	}
572 
573 	return 0;
574 }
575 
576 int inv_icm42600_buffer_init(struct inv_icm42600_state *st)
577 {
578 	unsigned int val;
579 	int ret;
580 
581 	/*
582 	 * Default FIFO configuration (bits 7 to 5)
583 	 * - use invalid value
584 	 * - FIFO count in bytes
585 	 * - FIFO count in big endian
586 	 */
587 	val = INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_ENDIAN;
588 	ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0,
589 				 GENMASK(7, 5), val);
590 	if (ret)
591 		return ret;
592 
593 	/*
594 	 * Enable FIFO partial read and continuous watermark interrupt.
595 	 * Disable all FIFO EN bits.
596 	 */
597 	val = INV_ICM42600_FIFO_CONFIG1_RESUME_PARTIAL_RD |
598 	      INV_ICM42600_FIFO_CONFIG1_WM_GT_TH;
599 	return regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1,
600 				  GENMASK(6, 5) | GENMASK(3, 0), val);
601 }
602