aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2014-11-11 22:01:44 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2014-11-14 14:22:34 -0500
commitc867b265b15c2703fe07adcce064a2e3ba77ed13 (patch)
tree9e182ae990e01bb0b90e9dc237e0ef2971352c2d /drivers/staging
parent5048907076ea8b31aa15a3ec7a6ce9c341eb77ce (diff)
[media] mn88472: move to staging
It is not ready enough to be released on mainline. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/Kconfig2
-rw-r--r--drivers/staging/media/Makefile1
-rw-r--r--drivers/staging/media/mn88472/Kconfig7
-rw-r--r--drivers/staging/media/mn88472/Makefile5
-rw-r--r--drivers/staging/media/mn88472/mn88472.c523
-rw-r--r--drivers/staging/media/mn88472/mn88472_priv.h36
6 files changed, 574 insertions, 0 deletions
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 655cf5037b0b..c2e675aa22c5 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -27,6 +27,8 @@ source "drivers/staging/media/davinci_vpfe/Kconfig"
27 27
28source "drivers/staging/media/dt3155v4l/Kconfig" 28source "drivers/staging/media/dt3155v4l/Kconfig"
29 29
30source "drivers/staging/media/mn88472/Kconfig"
31
30source "drivers/staging/media/omap24xx/Kconfig" 32source "drivers/staging/media/omap24xx/Kconfig"
31 33
32source "drivers/staging/media/omap4iss/Kconfig" 34source "drivers/staging/media/omap4iss/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index 6dbe578178cd..e174c57331e1 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -6,4 +6,5 @@ obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
6obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/ 6obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
7obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/ 7obj-$(CONFIG_VIDEO_OMAP2) += omap24xx/
8obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/ 8obj-$(CONFIG_VIDEO_TCM825X) += omap24xx/
9obj-$(CONFIG_DVB_MN88472) += mn88472/
9 10
diff --git a/drivers/staging/media/mn88472/Kconfig b/drivers/staging/media/mn88472/Kconfig
new file mode 100644
index 000000000000..a85c90a60bce
--- /dev/null
+++ b/drivers/staging/media/mn88472/Kconfig
@@ -0,0 +1,7 @@
1config DVB_MN88472
2 tristate "Panasonic MN88472"
3 depends on DVB_CORE && I2C
4 select REGMAP_I2C
5 default m if !MEDIA_SUBDRV_AUTOSELECT
6 help
7 Say Y when you want to support this frontend.
diff --git a/drivers/staging/media/mn88472/Makefile b/drivers/staging/media/mn88472/Makefile
new file mode 100644
index 000000000000..5987b7e6d82a
--- /dev/null
+++ b/drivers/staging/media/mn88472/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_DVB_MN88472) += mn88472.o
2
3ccflags-y += -Idrivers/media/dvb-core/
4ccflags-y += -Idrivers/media/dvb-frontends/
5ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/staging/media/mn88472/mn88472.c b/drivers/staging/media/mn88472/mn88472.c
new file mode 100644
index 000000000000..52de8f85d36c
--- /dev/null
+++ b/drivers/staging/media/mn88472/mn88472.c
@@ -0,0 +1,523 @@
1/*
2 * Panasonic MN88472 DVB-T/T2/C demodulator driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include "mn88472_priv.h"
18
19static int mn88472_get_tune_settings(struct dvb_frontend *fe,
20 struct dvb_frontend_tune_settings *s)
21{
22 s->min_delay_ms = 400;
23 return 0;
24}
25
26static int mn88472_set_frontend(struct dvb_frontend *fe)
27{
28 struct i2c_client *client = fe->demodulator_priv;
29 struct mn88472_dev *dev = i2c_get_clientdata(client);
30 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
31 int ret, i;
32 u32 if_frequency = 0;
33 u8 delivery_system_val, if_val[3], bw_val[7], bw_val2;
34
35 dev_dbg(&client->dev,
36 "delivery_system=%d modulation=%d frequency=%d symbol_rate=%d inversion=%d\n",
37 c->delivery_system, c->modulation,
38 c->frequency, c->symbol_rate, c->inversion);
39
40 if (!dev->warm) {
41 ret = -EAGAIN;
42 goto err;
43 }
44
45 switch (c->delivery_system) {
46 case SYS_DVBT:
47 delivery_system_val = 0x02;
48 break;
49 case SYS_DVBT2:
50 delivery_system_val = 0x03;
51 break;
52 case SYS_DVBC_ANNEX_A:
53 delivery_system_val = 0x04;
54 break;
55 default:
56 ret = -EINVAL;
57 goto err;
58 }
59
60 switch (c->delivery_system) {
61 case SYS_DVBT:
62 case SYS_DVBT2:
63 if (c->bandwidth_hz <= 6000000) {
64 /* IF 3570000 Hz, BW 6000000 Hz */
65 memcpy(if_val, "\x2c\x94\xdb", 3);
66 memcpy(bw_val, "\xbf\x55\x55\x15\x6b\x15\x6b", 7);
67 bw_val2 = 0x02;
68 } else if (c->bandwidth_hz <= 7000000) {
69 /* IF 4570000 Hz, BW 7000000 Hz */
70 memcpy(if_val, "\x39\x11\xbc", 3);
71 memcpy(bw_val, "\xa4\x00\x00\x0f\x2c\x0f\x2c", 7);
72 bw_val2 = 0x01;
73 } else if (c->bandwidth_hz <= 8000000) {
74 /* IF 4570000 Hz, BW 8000000 Hz */
75 memcpy(if_val, "\x39\x11\xbc", 3);
76 memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
77 bw_val2 = 0x00;
78 } else {
79 ret = -EINVAL;
80 goto err;
81 }
82 break;
83 case SYS_DVBC_ANNEX_A:
84 /* IF 5070000 Hz, BW 8000000 Hz */
85 memcpy(if_val, "\x3f\x50\x2c", 3);
86 memcpy(bw_val, "\x8f\x80\x00\x08\xee\x08\xee", 7);
87 bw_val2 = 0x00;
88 break;
89 default:
90 ret = -EINVAL;
91 goto err;
92 }
93
94 /* program tuner */
95 if (fe->ops.tuner_ops.set_params) {
96 ret = fe->ops.tuner_ops.set_params(fe);
97 if (ret)
98 goto err;
99 }
100
101 if (fe->ops.tuner_ops.get_if_frequency) {
102 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
103 if (ret)
104 goto err;
105
106 dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
107 }
108
109 switch (if_frequency) {
110 case 3570000:
111 case 4570000:
112 case 5070000:
113 break;
114 default:
115 dev_err(&client->dev, "IF frequency %d not supported\n",
116 if_frequency);
117 ret = -EINVAL;
118 goto err;
119 }
120
121 ret = regmap_write(dev->regmap[2], 0xfb, 0x13);
122 ret = regmap_write(dev->regmap[2], 0xef, 0x13);
123 ret = regmap_write(dev->regmap[2], 0xf9, 0x13);
124 if (ret)
125 goto err;
126
127 ret = regmap_write(dev->regmap[2], 0x00, 0x66);
128 if (ret)
129 goto err;
130 ret = regmap_write(dev->regmap[2], 0x01, 0x00);
131 if (ret)
132 goto err;
133 ret = regmap_write(dev->regmap[2], 0x02, 0x01);
134 if (ret)
135 goto err;
136 ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);
137 if (ret)
138 goto err;
139 ret = regmap_write(dev->regmap[2], 0x04, bw_val2);
140 if (ret)
141 goto err;
142
143 for (i = 0; i < sizeof(if_val); i++) {
144 ret = regmap_write(dev->regmap[2], 0x10 + i, if_val[i]);
145 if (ret)
146 goto err;
147 }
148
149 for (i = 0; i < sizeof(bw_val); i++) {
150 ret = regmap_write(dev->regmap[2], 0x13 + i, bw_val[i]);
151 if (ret)
152 goto err;
153 }
154
155 switch (c->delivery_system) {
156 case SYS_DVBT:
157 ret = regmap_write(dev->regmap[0], 0x07, 0x26);
158 ret = regmap_write(dev->regmap[0], 0xb0, 0x0a);
159 ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
160 ret = regmap_write(dev->regmap[0], 0xcd, 0x1f);
161 ret = regmap_write(dev->regmap[0], 0xd4, 0x0a);
162 ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
163 ret = regmap_write(dev->regmap[0], 0x00, 0xba);
164 ret = regmap_write(dev->regmap[0], 0x01, 0x13);
165 if (ret)
166 goto err;
167 break;
168 case SYS_DVBT2:
169 ret = regmap_write(dev->regmap[2], 0x2b, 0x13);
170 ret = regmap_write(dev->regmap[2], 0x4f, 0x05);
171 ret = regmap_write(dev->regmap[1], 0xf6, 0x05);
172 ret = regmap_write(dev->regmap[0], 0xb0, 0x0a);
173 ret = regmap_write(dev->regmap[0], 0xb4, 0xf6);
174 ret = regmap_write(dev->regmap[0], 0xcd, 0x01);
175 ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
176 ret = regmap_write(dev->regmap[0], 0xd6, 0x46);
177 ret = regmap_write(dev->regmap[2], 0x30, 0x80);
178 ret = regmap_write(dev->regmap[2], 0x32, 0x00);
179 if (ret)
180 goto err;
181 break;
182 case SYS_DVBC_ANNEX_A:
183 ret = regmap_write(dev->regmap[0], 0xb0, 0x0b);
184 ret = regmap_write(dev->regmap[0], 0xb4, 0x00);
185 ret = regmap_write(dev->regmap[0], 0xcd, 0x17);
186 ret = regmap_write(dev->regmap[0], 0xd4, 0x09);
187 ret = regmap_write(dev->regmap[0], 0xd6, 0x48);
188 ret = regmap_write(dev->regmap[1], 0x00, 0xb0);
189 if (ret)
190 goto err;
191 break;
192 default:
193 ret = -EINVAL;
194 goto err;
195 }
196
197 ret = regmap_write(dev->regmap[0], 0x46, 0x00);
198 ret = regmap_write(dev->regmap[0], 0xae, 0x00);
199 ret = regmap_write(dev->regmap[2], 0x08, 0x1d);
200 ret = regmap_write(dev->regmap[0], 0xd9, 0xe3);
201 ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);
202 if (ret)
203 goto err;
204
205 dev->delivery_system = c->delivery_system;
206
207 return 0;
208err:
209 dev_dbg(&client->dev, "failed=%d\n", ret);
210 return ret;
211}
212
213static int mn88472_read_status(struct dvb_frontend *fe, fe_status_t *status)
214{
215 struct i2c_client *client = fe->demodulator_priv;
216 struct mn88472_dev *dev = i2c_get_clientdata(client);
217 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
218 int ret;
219 unsigned int utmp;
220
221 *status = 0;
222
223 if (!dev->warm) {
224 ret = -EAGAIN;
225 goto err;
226 }
227
228 switch (c->delivery_system) {
229 case SYS_DVBT:
230 case SYS_DVBT2:
231 /* FIXME: implement me */
232 utmp = 0x08; /* DVB-C lock value */
233 break;
234 case SYS_DVBC_ANNEX_A:
235 ret = regmap_read(dev->regmap[1], 0x84, &utmp);
236 if (ret)
237 goto err;
238 break;
239 default:
240 ret = -EINVAL;
241 goto err;
242 }
243
244 if (utmp == 0x08)
245 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
246 FE_HAS_SYNC | FE_HAS_LOCK;
247
248 return 0;
249err:
250 dev_dbg(&client->dev, "failed=%d\n", ret);
251 return ret;
252}
253
254static int mn88472_init(struct dvb_frontend *fe)
255{
256 struct i2c_client *client = fe->demodulator_priv;
257 struct mn88472_dev *dev = i2c_get_clientdata(client);
258 int ret, len, remaining;
259 const struct firmware *fw = NULL;
260 u8 *fw_file = MN88472_FIRMWARE;
261
262 dev_dbg(&client->dev, "\n");
263
264 /* set cold state by default */
265 dev->warm = false;
266
267 /* power on */
268 ret = regmap_write(dev->regmap[2], 0x05, 0x00);
269 if (ret)
270 goto err;
271
272 ret = regmap_bulk_write(dev->regmap[2], 0x0b, "\x00\x00", 2);
273 if (ret)
274 goto err;
275
276 /* request the firmware, this will block and timeout */
277 ret = request_firmware(&fw, fw_file, &client->dev);
278 if (ret) {
279 dev_err(&client->dev, "firmare file '%s' not found\n",
280 fw_file);
281 goto err;
282 }
283
284 dev_info(&client->dev, "downloading firmware from file '%s'\n",
285 fw_file);
286
287 ret = regmap_write(dev->regmap[0], 0xf5, 0x03);
288 if (ret)
289 goto err;
290
291 for (remaining = fw->size; remaining > 0;
292 remaining -= (dev->i2c_wr_max - 1)) {
293 len = remaining;
294 if (len > (dev->i2c_wr_max - 1))
295 len = (dev->i2c_wr_max - 1);
296
297 ret = regmap_bulk_write(dev->regmap[0], 0xf6,
298 &fw->data[fw->size - remaining], len);
299 if (ret) {
300 dev_err(&client->dev,
301 "firmware download failed=%d\n", ret);
302 goto err;
303 }
304 }
305
306 ret = regmap_write(dev->regmap[0], 0xf5, 0x00);
307 if (ret)
308 goto err;
309
310 release_firmware(fw);
311 fw = NULL;
312
313 /* warm state */
314 dev->warm = true;
315
316 return 0;
317err:
318 if (fw)
319 release_firmware(fw);
320
321 dev_dbg(&client->dev, "failed=%d\n", ret);
322 return ret;
323}
324
325static int mn88472_sleep(struct dvb_frontend *fe)
326{
327 struct i2c_client *client = fe->demodulator_priv;
328 struct mn88472_dev *dev = i2c_get_clientdata(client);
329 int ret;
330
331 dev_dbg(&client->dev, "\n");
332
333 /* power off */
334 ret = regmap_write(dev->regmap[2], 0x0b, 0x30);
335
336 if (ret)
337 goto err;
338
339 ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
340 if (ret)
341 goto err;
342
343 dev->delivery_system = SYS_UNDEFINED;
344
345 return 0;
346err:
347 dev_dbg(&client->dev, "failed=%d\n", ret);
348 return ret;
349}
350
351static struct dvb_frontend_ops mn88472_ops = {
352 .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
353 .info = {
354 .name = "Panasonic MN88472",
355 .caps = FE_CAN_FEC_1_2 |
356 FE_CAN_FEC_2_3 |
357 FE_CAN_FEC_3_4 |
358 FE_CAN_FEC_5_6 |
359 FE_CAN_FEC_7_8 |
360 FE_CAN_FEC_AUTO |
361 FE_CAN_QPSK |
362 FE_CAN_QAM_16 |
363 FE_CAN_QAM_32 |
364 FE_CAN_QAM_64 |
365 FE_CAN_QAM_128 |
366 FE_CAN_QAM_256 |
367 FE_CAN_QAM_AUTO |
368 FE_CAN_TRANSMISSION_MODE_AUTO |
369 FE_CAN_GUARD_INTERVAL_AUTO |
370 FE_CAN_HIERARCHY_AUTO |
371 FE_CAN_MUTE_TS |
372 FE_CAN_2G_MODULATION |
373 FE_CAN_MULTISTREAM
374 },
375
376 .get_tune_settings = mn88472_get_tune_settings,
377
378 .init = mn88472_init,
379 .sleep = mn88472_sleep,
380
381 .set_frontend = mn88472_set_frontend,
382
383 .read_status = mn88472_read_status,
384};
385
386static int mn88472_probe(struct i2c_client *client,
387 const struct i2c_device_id *id)
388{
389 struct mn88472_config *config = client->dev.platform_data;
390 struct mn88472_dev *dev;
391 int ret;
392 unsigned int utmp;
393 static const struct regmap_config regmap_config = {
394 .reg_bits = 8,
395 .val_bits = 8,
396 };
397
398 dev_dbg(&client->dev, "\n");
399
400 /* Caller really need to provide pointer for frontend we create. */
401 if (config->fe == NULL) {
402 dev_err(&client->dev, "frontend pointer not defined\n");
403 ret = -EINVAL;
404 goto err;
405 }
406
407 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
408 if (dev == NULL) {
409 ret = -ENOMEM;
410 goto err;
411 }
412
413 dev->i2c_wr_max = config->i2c_wr_max;
414 dev->client[0] = client;
415 dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);
416 if (IS_ERR(dev->regmap[0])) {
417 ret = PTR_ERR(dev->regmap[0]);
418 goto err_kfree;
419 }
420
421 /* check demod answers to I2C */
422 ret = regmap_read(dev->regmap[0], 0x00, &utmp);
423 if (ret)
424 goto err_regmap_0_regmap_exit;
425
426 /*
427 * Chip has three I2C addresses for different register pages. Used
428 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
429 * 0x1a and 0x1c, in order to get own I2C client for each register page.
430 */
431 dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
432 if (dev->client[1] == NULL) {
433 ret = -ENODEV;
434 dev_err(&client->dev, "I2C registration failed\n");
435 if (ret)
436 goto err_regmap_0_regmap_exit;
437 }
438 dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);
439 if (IS_ERR(dev->regmap[1])) {
440 ret = PTR_ERR(dev->regmap[1]);
441 goto err_client_1_i2c_unregister_device;
442 }
443 i2c_set_clientdata(dev->client[1], dev);
444
445 dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
446 if (dev->client[2] == NULL) {
447 ret = -ENODEV;
448 dev_err(&client->dev, "2nd I2C registration failed\n");
449 if (ret)
450 goto err_regmap_1_regmap_exit;
451 }
452 dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);
453 if (IS_ERR(dev->regmap[2])) {
454 ret = PTR_ERR(dev->regmap[2]);
455 goto err_client_2_i2c_unregister_device;
456 }
457 i2c_set_clientdata(dev->client[2], dev);
458
459 /* create dvb_frontend */
460 memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));
461 dev->fe.demodulator_priv = client;
462 *config->fe = &dev->fe;
463 i2c_set_clientdata(client, dev);
464
465 dev_info(&client->dev, "Panasonic MN88472 successfully attached\n");
466 return 0;
467
468err_client_2_i2c_unregister_device:
469 i2c_unregister_device(dev->client[2]);
470err_regmap_1_regmap_exit:
471 regmap_exit(dev->regmap[1]);
472err_client_1_i2c_unregister_device:
473 i2c_unregister_device(dev->client[1]);
474err_regmap_0_regmap_exit:
475 regmap_exit(dev->regmap[0]);
476err_kfree:
477 kfree(dev);
478err:
479 dev_dbg(&client->dev, "failed=%d\n", ret);
480 return ret;
481}
482
483static int mn88472_remove(struct i2c_client *client)
484{
485 struct mn88472_dev *dev = i2c_get_clientdata(client);
486
487 dev_dbg(&client->dev, "\n");
488
489 regmap_exit(dev->regmap[2]);
490 i2c_unregister_device(dev->client[2]);
491
492 regmap_exit(dev->regmap[1]);
493 i2c_unregister_device(dev->client[1]);
494
495 regmap_exit(dev->regmap[0]);
496
497 kfree(dev);
498
499 return 0;
500}
501
502static const struct i2c_device_id mn88472_id_table[] = {
503 {"mn88472", 0},
504 {}
505};
506MODULE_DEVICE_TABLE(i2c, mn88472_id_table);
507
508static struct i2c_driver mn88472_driver = {
509 .driver = {
510 .owner = THIS_MODULE,
511 .name = "mn88472",
512 },
513 .probe = mn88472_probe,
514 .remove = mn88472_remove,
515 .id_table = mn88472_id_table,
516};
517
518module_i2c_driver(mn88472_driver);
519
520MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
521MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");
522MODULE_LICENSE("GPL");
523MODULE_FIRMWARE(MN88472_FIRMWARE);
diff --git a/drivers/staging/media/mn88472/mn88472_priv.h b/drivers/staging/media/mn88472/mn88472_priv.h
new file mode 100644
index 000000000000..1095949f040d
--- /dev/null
+++ b/drivers/staging/media/mn88472/mn88472_priv.h
@@ -0,0 +1,36 @@
1/*
2 * Panasonic MN88472 DVB-T/T2/C demodulator driver
3 *
4 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef MN88472_PRIV_H
18#define MN88472_PRIV_H
19
20#include "dvb_frontend.h"
21#include "mn88472.h"
22#include <linux/firmware.h>
23#include <linux/regmap.h>
24
25#define MN88472_FIRMWARE "dvb-demod-mn88472-02.fw"
26
27struct mn88472_dev {
28 struct i2c_client *client[3];
29 struct regmap *regmap[3];
30 struct dvb_frontend fe;
31 u16 i2c_wr_max;
32 fe_delivery_system_t delivery_system;
33 bool warm; /* FW running */
34};
35
36#endif