blob: 479c5f96bd80550cc94c8ab52ff864fe4cbb2b2b [file] [log] [blame]
Shad Ansari2f7f9be2017-06-07 13:34:53 -07001/*
2<:copyright-BRCM:2016:DUAL/GPL:standard
3
4 Broadcom Proprietary and Confidential.(c) 2016 Broadcom
5 All Rights Reserved
6
7Unless you and Broadcom execute a separate written software license
8agreement governing use of this software, this software is licensed
9to you under the terms of the GNU General Public License version 2
10(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
11with the following added to such license:
12
13 As a special exception, the copyright holders of this software give
14 you permission to link this software with independent modules, and
15 to copy and distribute the resulting executable under terms of your
16 choice, provided that you also meet, for each linked independent
17 module, the terms and conditions of the license of that module.
18 An independent module is a module which is not derived from this
19 software. The special exception does not apply to any modifications
20 of the software.
21
22Not withstanding the above, under no circumstances may you combine
23this software in any way with any other Broadcom software provided
24under a license other than the GPL, without Broadcom's express prior
25written consent.
26
27:>
28*/
29#include <sys/ioctl.h>
30#include <sys/types.h>
31#include <sys/stat.h>
32#include <fcntl.h>
33#include <bcmcli.h>
34#include <bcmolt_i2c_devs_ioctl.h>
35#include <bcmolt_dev_ctrl_ioctl.h>
36#include <bcmolt_api.h>
37#include <bcmolt_model_types.h>
38#include <bcmolt_fld.h>
39#include "bcmolt_board.h"
40#include "bcmolt_dpll_table.h"
41
42#define BCM_I2C_DEV_ADDR_START typedef enum {
43#define BCM_I2C_DEV_ADDR(name, desc, val) name = val,
44#define BCM_I2C_DEV_ADDR_END } bcm_i2c_dev_addr;
45
46#define BCM_FPGA_REG_FPGA_VERSION 0x0
47#define BCM_FPGA_REG_BOARD_CONF 0x1
48#define BCM_FPGA_REG_RESETS 0x2
49/* Enable/disable transceiver */
50#define BCM_FPGA_REG_TRX_ENABLE 0x3
51#define BCM_FPGA_REG_TRX_FAIL 0x4
52/* Is transceiver present ? */
53#define BCM_FPGA_REG_TRX_IS_PRESENT 0x5
54#define BCM_FPGA_REG_CXP_CONTROLS 0x6
55#define BCM_FPGA_REG_SHIFT_REGISTER_DATA 0x7
56#define BCM_FPGA_REG_SHIFT_REGISTER_CONTROL 0x8
57#define BCM_FPGA_REG_LEDS 0x9
58#define BCM_FPGA_REG_DEBUG_LEDS 0xA
59#define BCM_FPGA_REG_GPIO_DIR 0xB
60#define BCM_FPGA_REG_GPIO_INPUT 0xC
61#define BCM_FPGA_REG_GPIO_OUTPUT 0xD
62#define BCM_FPGA_REG_GPIO_IRQ 0xE
63
64#define BCM_FPGA_REG_LOW BCM_FPGA_REG_FPGA_VERSION
65#define BCM_FPGA_REG_HIGH BCM_FPGA_REG_GPIO_IRQ
66
67#define BCM_RST_BIT_DEVICE 0x0
68#define BCM_RST_BIT_PON_DPLL 0x1
69#define BCM_RST_BIT_PM_DPLL 0x2
70#define BCM_RST_BIT_KT2 0x4
71
72#define SVK4_IDENT_FILE "/etc/svk4"
73
74#include <bcmolt_i2c_devs_addr.h>
75
76#define MAX_CMD_STR_LEN 1024
77
78/* Since the board driver configuration is specific for Linux, there is no point using OS abstraction layer to perform operations like ioctl(). */
79
80static int maple_i2c_fd;
81static int maple_dev_ctrl_fd;
82
83static bcmos_bool bcm_board_is_svk4(void)
84{
85 bcmos_bool is_svk4 = BCMOS_FALSE;
86 FILE *f = fopen(SVK4_IDENT_FILE, "r");
87 if (f)
88 {
89 is_svk4 = BCMOS_TRUE;
90 fclose(f);
91 }
92 return is_svk4;
93}
94
95static bcmos_errno bcm_access_fpga(void)
96{
97 bcmos_errno rc;
98 if (bcm_board_is_svk4())
99 {
100 rc = bcm_board_dev_change(I2C_SW1_I2C_ADDR);
101 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW1_I2C_ADDR) failed\n");
102 rc = bcm_board_switch_write(0x4);
103 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(1) failed\n");
104 }
105 else
106 {
107 rc = bcm_board_dev_change(I2C_SW0_I2C_ADDR);
108 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW0_I2C_ADDR) failed\n");
109 rc = bcm_board_switch_write(1);
110 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(1) failed\n");
111 }
112 rc = bcm_board_dev_change(FPGA_I2C_ADDR);
113 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(FPGA_I2C_ADDR) failed \n");
114
115 return BCM_ERR_OK;
116}
117
118bcmos_errno bcm_board_dev_change(uint32_t addr)
119{
120 int rc;
121 maple_i2c_ioctl_param params =
122 {
123 .addr = addr,
124 };
125
126 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_CHANGE, &params);
127 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
128
129 return BCM_ERR_OK;
130}
131
132bcmos_errno bcm_board_dev_write(uint32_t count, uint32_t addr, uint32_t val)
133{
134 int rc;
135 maple_i2c_ioctl_param params =
136 {
137 .count = count,
138 .addr = addr,
139 .val = val,
140 };
141
142 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
143 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
144
145 return BCM_ERR_OK;
146}
147
148bcmos_errno bcm_board_dev_read(uint32_t count, uint32_t addr, uint32_t *val)
149{
150 int rc;
151 maple_i2c_ioctl_param params =
152 {
153 .count = count,
154 .addr = addr,
155 };
156
157 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_READ, &params);
158 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
159 *val = params.val;
160
161 return BCM_ERR_OK;
162}
163
164bcmos_errno bcm_board_switch_write(uint32_t val)
165{
166 int rc;
167 maple_i2c_ioctl_param params =
168 {
169 .val = val,
170 };
171
172 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_SWITCH_WRITE, &params);
173 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
174
175 return BCM_ERR_OK;
176}
177
178bcmos_errno bcm_board_switch_read(uint32_t *val)
179{
180 int rc;
181 maple_i2c_ioctl_param params = {};
182
183 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_SWITCH_READ, &params);
184 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for maple_i2c_fd\n");
185 *val = params.val;
186
187 return BCM_ERR_OK;
188}
189
190bcmos_errno bcm_board_fpga_write(uint32_t addr, uint32_t val)
191{
192 int rc;
193 maple_i2c_ioctl_param params =
194 {
195 .addr = addr,
196 .val = val,
197 };
198
199 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_FPGA_WRITE, &params);
200 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for fpga_write\n");
201
202 return BCM_ERR_OK;
203}
204
205bcmos_errno bcm_board_host_event_write(uint32_t val)
206{
207 int rc;
208 dev_ctrl_ioctl_param params =
209 {
210 .event = val,
211 };
212
213 rc = ioctl(maple_dev_ctrl_fd, MAPLE_DEV_CTRL_IOCTL_OP_HOST_EVENT_WRITE, &params);
214 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for host_event_write\n");
215
216#ifdef CONFIG_ONU_SIM
217 /* Raise an interrupt on ext_irq1 for the embedded side. */
218 rc = bcm_board_fpga_gen_gpio_irq(BCMOLT_EXT_IRQ_EXT_IRQ1);
219 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for bcm_board_fpga_gen_gpio_irq\n");
220#endif
221
222 return BCM_ERR_OK;
223}
224
225bcmos_errno bcm_board_pci_debug(uint32_t device, uint32_t command, int32_t start, int32_t howmany, uint32_t *dumpptr)
226{
227 int rc;
228 dev_ctrl_ioctl_param params =
229 {
230 .device = device,
231 .dumpptr = dumpptr,
232 .start_index = start,
233 .howmany = howmany
234 };
235
236 rc = ioctl(maple_dev_ctrl_fd, command, &params);
237 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for dev_ctrl\n");
238
239 return BCM_ERR_OK;
240}
241bcmos_errno bcm_board_fpga_read(uint32_t addr, uint32_t *val)
242{
243 int rc;
244 maple_i2c_ioctl_param params =
245 {
246 .addr = addr,
247 };
248
249 rc = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_FPGA_READ, &params);
250 BCMOS_TRACE_CHECK_RETURN(rc, BCM_ERR_INTERNAL, "ioctl failed for fpga_read\n");
251 *val = params.val;
252
253 return BCM_ERR_OK;
254}
255
256bcmos_errno bcm_board_fpga_reg_read(uint32_t reg, uint32_t *val)
257{
258 bcmos_errno rc;
259
260 if (reg > BCM_FPGA_REG_HIGH)
261 return BCM_ERR_RANGE;
262
263 rc = bcm_access_fpga();
264 BCMOS_CHECK_RETURN(rc, rc, rc);
265
266 return bcm_board_fpga_read(reg, val);
267}
268
269bcmos_errno bcm_board_fpga_reg_write(uint32_t reg, uint32_t val)
270{
271 bcmos_errno rc;
272
273 if (reg > BCM_FPGA_REG_HIGH)
274 return BCM_ERR_RANGE;
275
276 rc = bcm_access_fpga();
277 BCMOS_CHECK_RETURN(rc, rc, rc);
278
279 return bcm_board_fpga_write(reg, val);
280}
281
282bcmos_errno bcm_board_fpga_version_get(uint32_t *version)
283{
284 bcmos_errno rc;
285
286 rc = bcm_access_fpga();
287 BCMOS_CHECK_RETURN(rc, rc, rc);
288
289 return bcm_board_fpga_read(BCM_FPGA_REG_FPGA_VERSION, version);
290}
291
292bcmos_errno bcm_board_fpga_set_gpio_dir(bcmolt_gpio_pin gpio_pin, bcm_fpga_gpio_dir dir)
293{
294 bcmos_errno rc;
295 uint32_t gpio_dir_mask;
296
297 rc = bcm_access_fpga();
298 BCMOS_CHECK_RETURN(rc, rc, rc);
299
300 /* Read-modify-write direction register (we don't want to affect other GPIO's). */
301 rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_DIR, &gpio_dir_mask);
302 BCMOS_CHECK_RETURN(rc, rc, rc);
303 if (dir == BCM_FPGA_GPIO_DIR_INPUT)
304 gpio_dir_mask &= ~(1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
305 else
306 gpio_dir_mask |= (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
307
308 return bcm_board_fpga_write(BCM_FPGA_REG_GPIO_DIR, gpio_dir_mask);
309}
310
311bcmos_errno bcm_board_fpga_get_gpio_dir(bcmolt_gpio_pin gpio_pin, bcm_fpga_gpio_dir *dir)
312{
313 bcmos_errno rc;
314 uint32_t gpio_dir_mask;
315
316 rc = bcm_access_fpga();
317 BCMOS_CHECK_RETURN(rc, rc, rc);
318
319 rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_DIR, &gpio_dir_mask);
320 BCMOS_CHECK_RETURN(rc, rc, rc);
321
322 *dir = (gpio_dir_mask & (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4))) ? BCM_FPGA_GPIO_DIR_OUTPUT : BCM_FPGA_GPIO_DIR_INPUT;
323
324 return rc;
325}
326
327bcmos_errno bcm_board_fpga_write_gpio(bcmolt_gpio_pin gpio_pin, uint32_t val)
328{
329 bcmos_errno rc;
330 uint32_t gpio_write_mask;
331
332 rc = bcm_access_fpga();
333 BCMOS_CHECK_RETURN(rc, rc, rc);
334
335 /* Read-modify-write direction register (we don't want to affect other GPIO's). */
336 rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_OUTPUT, &gpio_write_mask);
337 BCMOS_CHECK_RETURN(rc, rc, rc);
338 if (!val)
339 gpio_write_mask &= ~(1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
340 else
341 gpio_write_mask |= (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4));
342
343 return bcm_board_fpga_write(BCM_FPGA_REG_GPIO_OUTPUT, gpio_write_mask);
344}
345
346bcmos_errno bcm_board_fpga_read_gpio(bcmolt_gpio_pin gpio_pin, uint32_t *val)
347{
348 bcmos_errno rc;
349 uint32_t gpio_read_mask;
350
351 rc = bcm_access_fpga();
352 BCMOS_CHECK_RETURN(rc, rc, rc);
353
354 rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_INPUT, &gpio_read_mask);
355 BCMOS_CHECK_RETURN(rc, rc, rc);
356
357 *val = (gpio_read_mask & (1 << (gpio_pin - BCMOLT_GPIO_PIN_PIN4)));
358
359 return rc;
360}
361
362bcmos_errno bcm_board_fpga_gen_gpio_irq(bcmolt_ext_irq ext_irq)
363{
364 bcmos_errno rc;
365 uint32_t gpio_irq_mask;
366
367 rc = bcm_access_fpga();
368 BCMOS_CHECK_RETURN(rc, rc, rc);
369
370 /* Read-modify-write direction register (we don't want to affect other GPIO's). */
371 rc = bcm_board_fpga_read(BCM_FPGA_REG_GPIO_IRQ, &gpio_irq_mask);
372 BCMOS_CHECK_RETURN(rc, rc, rc);
373
374 gpio_irq_mask |= (1 << ext_irq);
375 rc = bcm_board_fpga_write(BCM_FPGA_REG_GPIO_IRQ, gpio_irq_mask);
376 BCMOS_CHECK_RETURN(rc, rc, rc);
377
378 bcmos_usleep(1000);
379
380 gpio_irq_mask &= ~(1 << ext_irq);
381 rc = bcm_board_fpga_write(BCM_FPGA_REG_GPIO_IRQ, gpio_irq_mask);
382
383 return rc;
384}
385
386bcmos_errno bcm_board_trx_present(uint8_t pon)
387{
388 bcmos_errno rc;
389 uint32_t trx_absence_mask;
390
391 rc = bcm_access_fpga();
392 BCMOS_CHECK_RETURN(rc, rc, rc);
393
394 /* Check that the transceiver is present (plugged in). For ONU simulator, we allow working without transceivers. */
395 rc = bcm_board_fpga_read(BCM_FPGA_REG_TRX_IS_PRESENT, &trx_absence_mask);
396 BCMOS_CHECK_RETURN(rc, rc, rc);
397
398 if (trx_absence_mask & (1 << pon))
399 {
400 /* The transceiver is absent. */
401 return BCM_ERR_NODEV;
402 }
403 return BCM_ERR_OK;
404}
405
406bcmos_errno bcm_board_trx_enable(uint8_t pon, bcmos_bool is_enabled)
407{
408#ifdef CONFIG_ONU_SIM
409 static uint32_t trx_disable_mask = 0xFFFFFFFF;
410
411 /* Keep track of which TRXs are logically enabled. */
412 if (is_enabled)
413 trx_disable_mask &= ~(1 << pon);
414 else
415 trx_disable_mask |= (1 << pon);
416
417 return bcm_board_host_event_write(trx_disable_mask);
418#else
419 uint32_t trx_disable_mask;
420 uint32_t trx_absence_mask;
421
422 bcmos_errno rc = bcm_access_fpga();
423 BCMOS_CHECK_RETURN(rc, rc, rc);
424
425 /* Check that the transceiver is present (plugged in). */
426 rc = bcm_board_fpga_read(BCM_FPGA_REG_TRX_IS_PRESENT, &trx_absence_mask);
427 BCMOS_CHECK_RETURN(rc, rc, rc);
428 if (trx_absence_mask & (1 << pon))
429 {
430 /* The transceiver is absent. */
431 return BCM_ERR_NODEV;
432 }
433
434 /* Read-modify-write transceiver disable mask (we don't want to affect other PON's). */
435 rc = bcm_board_fpga_read(BCM_FPGA_REG_TRX_ENABLE, &trx_disable_mask);
436 BCMOS_CHECK_RETURN(rc, rc, rc);
437 if (is_enabled == BCMOS_TRUE)
438 trx_disable_mask &= ~(1 << pon);
439 else
440 trx_disable_mask |= (1 << pon);
441
442 rc = bcm_board_fpga_write(BCM_FPGA_REG_TRX_ENABLE, trx_disable_mask);
443 if (rc != BCM_ERR_OK)
444 return BCM_ERR_INTERNAL;
445 return bcm_board_host_event_write(trx_disable_mask);
446#endif
447}
448
449static bcmos_errno bcm_board_config_reset_value(uint32_t rst_bit, bcmos_bool is_on)
450{
451 bcmos_errno rc;
452 uint32_t reset_values;
453
454 rc = bcm_access_fpga();
455 BCMOS_CHECK_RETURN(rc, rc, rc);
456
457 /* Read-modify-write so we can set only the relevant bit to 0 */
458 rc = bcm_board_fpga_read(BCM_FPGA_REG_RESETS, &reset_values);
459 BCMOS_CHECK_RETURN(rc, rc, rc);
460
461 if (is_on == BCMOS_TRUE)
462 reset_values |= 1 << rst_bit;
463 else
464 reset_values &= ~(1 << rst_bit);
465
466 return bcm_board_fpga_write(BCM_FPGA_REG_RESETS, reset_values);
467}
468
469static bcmos_errno device_disconnect(void)
470{
471 bcmolt_device_key key = {};
472 bcmolt_device_cfg dev_cfg;
473 bcmolt_device_disconnect dev_disconnect;
474 bcmos_errno rc;
475
476 BCMOLT_CFG_INIT(&dev_cfg, device, key);
477 BCMOLT_CFG_PROP_GET(&dev_cfg, device, state);
478 rc = bcmolt_cfg_get(0, &dev_cfg.hdr);
479 BCMOS_CHECK_RETURN(rc, rc, rc);
480 if (dev_cfg.data.state != BCMOLT_DEVICE_STATE_DISCONNECTED)
481 {
482 BCMOLT_OPER_INIT(&dev_disconnect, device, disconnect, key);
483 return bcmolt_oper_submit(0, &dev_disconnect.hdr);
484 }
485 else
486 return BCM_ERR_OK;
487}
488
489bcmos_errno bcm_board_device_reset(void)
490{
491 bcmos_errno rc;
492
493 rc = device_disconnect();
494 BCMOS_CHECK_RETURN(rc, rc, rc);
495 rc = bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_FALSE);
496 BCMOS_CHECK_RETURN(rc, rc, rc);
497
498 return bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_TRUE);
499}
500
501/* Device on keeps the reset bit on active high */
502bcmos_errno bcm_board_device_on(void)
503{
504 return bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_TRUE);
505}
506
507/* Device off keeps the reset bit on active low */
508bcmos_errno bcm_board_device_off(void)
509{
510 bcmos_errno rc;
511
512 rc = device_disconnect();
513 BCMOS_CHECK_RETURN(rc, rc, rc);
514
515 return bcm_board_config_reset_value(BCM_RST_BIT_DEVICE, BCMOS_FALSE);
516}
517
518/* Katana2 Device on keeps the reset bit on active high */
519bcmos_errno bcm_board_kt2_device_on(void)
520{
521 /* take the KT2 out of reset */
522 return bcm_board_config_reset_value(BCM_RST_BIT_KT2, BCMOS_TRUE);
523}
524
525/* Device off keeps the reset bit on active low */
526bcmos_errno bcm_board_kt2_device_off(void)
527{
528 return bcm_board_config_reset_value(BCM_RST_BIT_KT2, BCMOS_FALSE);
529}
530
531static bcmos_errno bcm_access_dpll(void)
532{
533 bcmos_errno rc;
534
535 if (bcm_board_is_svk4())
536 {
537 rc = bcm_board_dev_change(I2C_SW1_I2C_ADDR);
538 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW1_I2C_ADDR) failed\n");
539 rc = bcm_board_switch_write(0x20);
540 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(0x20) failed\n");
541 }
542 else
543 {
544 rc = bcm_board_dev_change(I2C_SW0_I2C_ADDR);
545 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(I2C_SW0_I2C_ADDR) failed\n");
546 rc = bcm_board_switch_write(2);
547 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_switch_write(2) failed\n");
548 }
549
550 rc = bcm_board_dev_change(PON_DPLL_I2C_ADDR);
551 BCMOS_TRACE_CHECK_RETURN(rc, rc, "bcm_board_dev_change(PON_DPLL_I2C_ADDR) failed \n");
552
553 return rc;
554}
555
556static int bcm_board_set_page_dpll(uint32_t page)
557{
558 int rcioctl;
559 maple_i2c_ioctl_param params =
560 {
561 .count = 8,
562 .addr = 1,
563 .val = page,
564 };
565
566 rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
567 BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl write change page failed\n");
568
569 return BCM_ERR_OK;
570}
571
572bcmos_errno bcm_board_read_dpll(uint32_t page, uint32_t reg, uint32_t *val)
573{
574 bcmos_errno rc;
575 int rcioctl;
576 maple_i2c_ioctl_param params =
577 {
578 .count = 8,
579 .addr = reg,
580 .val = 0,
581 };
582
583 rc = bcm_access_dpll();
584 bcm_board_set_page_dpll(page);
585 rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_READ, &params);
586 BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl read failed for maple_i2c_fd\n");
587 *val = params.val;
588
589 return rc;
590}
591
592bcmos_errno bcm_board_write_dpll(uint32_t page, uint32_t reg, uint32_t val)
593{
594 bcmos_errno rc;
595 int rcioctl;
596 maple_i2c_ioctl_param params =
597 {
598 .count = 8,
599 .addr = reg,
600 .val = val,
601 };
602
603 rc = bcm_access_dpll();
604 bcm_board_set_page_dpll(page);
605 rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
606 BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl write failed for maple_i2c_fd\n");
607
608 return rc;
609}
610
611static bcmos_errno bcm_board_load_dpll(dpll_command *commands, int cmdlen)
612{
613 int rcioctl,i;
614 bcmos_errno rc;
615 uint8_t previous_page = 0;
616
617 maple_i2c_ioctl_param params =
618 {
619 .count = 8,
620 .addr = 0,
621 .val = 0,
622 };
623
624 rc = bcm_access_dpll();
625 for (i=0; i < cmdlen; i++)
626 {
627 if (commands[i].page != previous_page)
628 {
629 bcm_board_set_page_dpll(commands[i].page);
630 previous_page = commands[i].page;
631 }
632 params.addr = commands[i].reg;
633 params.val = commands[i].data;
634 rcioctl = ioctl(maple_i2c_fd, MAPLE_I2C_IOCTL_OP_DEV_WRITE, &params);
635 BCMOS_TRACE_CHECK_RETURN(rcioctl, BCM_ERR_INTERNAL, "ioctl write data page failed\n");
636 }
637 return rc;
638}
639bcmos_errno bcm_board_burn_pon_dpll(bcm_dpll_users dpll_dev)
640{
641 switch(dpll_dev)
642 {
643 case GPON_DPLL:
644 return bcm_board_load_dpll(gpon_dpll_table,sizeof(gpon_dpll_table)/sizeof(dpll_command));
645 break;
646 case EPON_DPLL:
647 return bcm_board_load_dpll(epon_dpll_table,sizeof(epon_dpll_table)/sizeof(dpll_command));
648 break;
649 case GPON_SYNCE:
650 return bcm_board_load_dpll(gpon_synce_dpll_table,sizeof(gpon_synce_dpll_table)/sizeof(dpll_command));
651 break;
652 default:
653 break;
654 }
655
656 return BCM_ERR_PARM;
657}
658
659bcmos_errno bcm_board_init(void)
660{
661 maple_dev_ctrl_fd = open("/dev/maple_dev_ctrl", O_RDWR);
662 BCMOS_TRACE_CHECK_RETURN(maple_dev_ctrl_fd < 0, errno, "maple_dev_ctrl_fd open failed\n");
663
664 maple_i2c_fd = open("/dev/maple_i2c", O_RDWR);
665 BCMOS_TRACE_CHECK_RETURN(maple_i2c_fd < 0, errno, "maple_i2c_fd open failed\n");
666
667#ifdef CONFIG_ONU_SIM
668 /* If the ONU sim is running, always leave all transceivers physically disabled. */
669 bcmos_errno rc = bcm_access_fpga();
670 BCMOS_CHECK_RETURN(rc, rc, rc);
671 rc = bcm_board_fpga_write(BCM_FPGA_REG_TRX_ENABLE, 0xFFFFFFFF);
672 if (rc != BCM_ERR_OK)
673 return BCM_ERR_INTERNAL;
674#endif
675
676 return BCM_ERR_OK;
677}
678
679bcmos_errno bcm_board_get_board_id(bcm_board_svk_board_id * board_id)
680{
681 bcmos_errno rc;
682 uint32_t val;
683
684 rc = bcm_access_fpga();
685 BCMOS_CHECK_RETURN(rc, rc, rc);
686
687 rc = bcm_board_fpga_read(0x1, &val);
688 BCMOS_CHECK_RETURN(rc, rc, rc);
689
690 *board_id = val & 0x7;
691 return BCM_ERR_OK;
692}
693
694void bcm_board_uninit(void)
695{
696 close(maple_i2c_fd);
697 maple_i2c_fd = 0;
698
699 close(maple_dev_ctrl_fd);
700 maple_dev_ctrl_fd = -1;
701}
702