Lines Matching refs:i2c

46 #include <sys/i2c/clients/i2c_client.h>
47 #include <sys/i2c/misc/i2c_svc.h>
48 #include <sys/i2c/misc/i2c_svc_impl.h>
49 #include <sys/i2c/nexus/pcf8584.h>
70 static void pcf8584_select_bus(pcf8584_t *i2c);
72 static void pcf8584_put_s1(pcf8584_t *i2c, char cmd);
73 static void pcf8584_put_s0(pcf8584_t *i2c, char data);
74 static uint8_t pcf8584_get_s0(pcf8584_t *i2c);
75 static uint8_t pcf8584_get_s1(pcf8584_t *i2c);
76 static int pcf8584_bbn_ready(pcf8584_t *i2c);
77 static int pcf8584_error(int status, uint8_t rdwr, pcf8584_t *i2c);
78 static void pcf8584_monitor_mode(pcf8584_t *i2c);
81 static void pcf8584_init(pcf8584_t *i2c);
82 static int pcf8584_setup_regs(dev_info_t *dip, pcf8584_t *i2c);
83 static void pcf8584_free_regs(pcf8584_t *i2c);
87 static int pcf8584_process(pcf8584_t *i2c, uint8_t s1);
90 static void pcf8584_do_polled_io(pcf8584_t *i2c);
91 static void pcf8584_take_over(pcf8584_t *i2c, dev_info_t *dip,
93 static void pcf8584_give_up(pcf8584_t *i2c, kcondvar_t *waiter, int saved_mode);
279 pcf8584_t *i2c;
282 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, instance);
284 if ((i2c->pcf8584_attachflags & ADD_INTR) != 0) {
285 ddi_remove_intr(dip, 0, i2c->pcf8584_icookie);
288 cv_destroy(&i2c->pcf8584_cv);
290 if ((i2c->pcf8584_attachflags & IMUTEX) != 0) {
291 mutex_destroy(&i2c->pcf8584_imutex);
292 cv_destroy(&i2c->pcf8584_icv);
294 if ((i2c->pcf8584_attachflags & SETUP_REGS) != 0) {
295 pcf8584_free_regs(i2c);
297 if ((i2c->pcf8584_attachflags & NEXUS_REGISTER) != 0) {
300 if ((i2c->pcf8584_attachflags & PROP_CREATE) != 0) {
304 if ((i2c->pcf8584_attachflags & MINOR_NODE) != 0) {
314 pcf8584_t *i2c;
325 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, instance);
327 i2c->pcf8584_dip = dip;
329 (void) snprintf(i2c->pcf8584_name, sizeof (i2c->pcf8584_name),
335 if (strcmp(ddi_binding_name(i2c->pcf8584_dip), "SUNW,bbc-i2c") == 0) {
336 i2c->pcf8584_impl_type = BBC;
337 i2c->pcf8584_impl_delay = PCF8584_GENERIC_DELAY;
338 } else if (strcmp(ddi_binding_name(i2c->pcf8584_dip),
339 "SUNW,i2c-pic16f747") == 0) {
340 i2c->pcf8584_impl_type = PIC16F747;
341 i2c->pcf8584_impl_delay = PCF8584_PIC16F747_DELAY;
343 i2c->pcf8584_impl_type = GENERIC;
344 i2c->pcf8584_impl_delay = PCF8584_GENERIC_DELAY;
354 i2c->pcf8584_attachflags |= PROP_CREATE;
357 cv_init(&i2c->pcf8584_cv, NULL, CV_DRIVER, NULL);
359 if (pcf8584_setup_regs(dip, i2c) != DDI_SUCCESS) {
363 i2c->pcf8584_attachflags |= SETUP_REGS;
367 i2c->pcf8584_mode = PCF8584_POLL_MODE;
371 &i2c->pcf8584_icookie) == DDI_SUCCESS) {
372 mutex_init(&i2c->pcf8584_imutex, NULL, MUTEX_DRIVER,
373 (void *)i2c->pcf8584_icookie);
374 cv_init(&i2c->pcf8584_icv, NULL, CV_DRIVER, NULL);
375 i2c->pcf8584_attachflags |= IMUTEX;
378 (caddr_t)i2c) == DDI_SUCCESS) {
379 i2c->pcf8584_attachflags |= ADD_INTR;
380 i2c->pcf8584_mode = PCF8584_INTR_MODE;
383 i2c->pcf8584_name);
384 i2c->pcf8584_mode = PCF8584_POLL_MODE;
388 "Operating in POLL MODE only", i2c->pcf8584_name);
389 i2c->pcf8584_mode = PCF8584_POLL_MODE;
396 if ((i2c->pcf8584_attachflags & IMUTEX) == 0) {
397 cv_init(&i2c->pcf8584_icv, NULL, CV_DRIVER, NULL);
398 mutex_init(&i2c->pcf8584_imutex, NULL, MUTEX_DRIVER, NULL);
399 i2c->pcf8584_attachflags |= IMUTEX;
403 i2c->pcf8584_attachflags |= NEXUS_REGISTER;
408 i2c->pcf8584_name);
412 i2c->pcf8584_attachflags |= MINOR_NODE;
414 pcf8584_init(i2c);
416 i2c->pcf8584_nexus_dip = dip;
466 pcf8584_t *i2c;
475 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, instance);
476 if (i2c == NULL)
482 mutex_enter(&i2c->pcf8584_imutex);
483 if (i2c->pcf8584_open) {
484 mutex_exit(&i2c->pcf8584_imutex);
488 i2c->pcf8584_open = 1;
489 mutex_exit(&i2c->pcf8584_imutex);
499 pcf8584_t *i2c;
508 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, instance);
509 if (i2c == NULL)
512 mutex_enter(&i2c->pcf8584_imutex);
513 i2c->pcf8584_open = 0;
514 mutex_exit(&i2c->pcf8584_imutex);
524 pcf8584_t *i2c;
529 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, getminor(dev));
530 if (i2c == NULL)
533 self = (dev_info_t *)i2c->pcf8584_nexus_dip;
603 pcf8584_t *i2c;
607 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, instance);
609 pcf8584_acquire(i2c, NULL, NULL, B_FALSE);
614 * the hold that was placed on the i2c bus, which allows any real
620 pcf8584_t *i2c;
624 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state, instance);
626 pcf8584_release(i2c, B_FALSE);
628 pcf8584_init(i2c);
637 pcf8584_acquire(pcf8584_t *i2c, dev_info_t *dip, i2c_transfer_t *tp,
641 i2c->pcf8584_busy = 1;
642 i2c->pcf8584_cur_tran = tp;
643 i2c->pcf8584_cur_dip = dip;
644 i2c->pcf8584_cur_status = PCF8584_TRANSFER_NEW;
648 mutex_enter(&i2c->pcf8584_imutex);
649 while (i2c->pcf8584_busy) {
650 cv_wait(&i2c->pcf8584_cv, &i2c->pcf8584_imutex);
652 i2c->pcf8584_busy = 1;
653 mutex_exit(&i2c->pcf8584_imutex);
665 plat_shared_i2c_enter(i2c->pcf8584_dip);
668 mutex_enter(&i2c->pcf8584_imutex);
669 i2c->pcf8584_cur_tran = tp;
670 i2c->pcf8584_cur_dip = dip;
671 mutex_exit(&i2c->pcf8584_imutex);
678 pcf8584_release(pcf8584_t *i2c, boolean_t force)
681 i2c->pcf8584_busy = 0;
682 i2c->pcf8584_cur_tran = NULL;
683 i2c->pcf8584_cur_dip = NULL;
684 i2c->pcf8584_cur_status = PCF8584_TRANSFER_OVER;
685 cv_signal(&i2c->pcf8584_cv);
689 mutex_enter(&i2c->pcf8584_imutex);
690 i2c->pcf8584_busy = 0;
691 i2c->pcf8584_cur_tran = NULL;
692 cv_signal(&i2c->pcf8584_cv);
693 mutex_exit(&i2c->pcf8584_imutex);
695 if ((&plat_shared_i2c_exit != NULL) && (i2c->pcf8584_cur_dip != NULL)) {
696 plat_shared_i2c_exit(i2c->pcf8584_dip);
706 pcf8584_select_bus(pcf8584_t *i2c)
717 i2c->pcf8584_b_reg));
718 if (i2c->pcf8584_b_reg != NULL) {
719 ppvt = ddi_get_parent_data(i2c->pcf8584_cur_dip);
726 ddi_put8(i2c->pcf8584_b_rhandle, i2c->pcf8584_b_reg, bus);
757 pcf8584_put_s1(pcf8584_t *i2c, char cmd)
759 ddi_acc_handle_t hp = i2c->pcf8584_rhandle;
760 pcf8584_regs_t *rp = &i2c->pcf8584_regs;
763 PCF8584_IMPL_DELAY(i2c->pcf8584_impl_type,
764 i2c->pcf8584_impl_delay);
769 PCF8584_IMPL_DELAY(i2c->pcf8584_impl_type,
770 i2c->pcf8584_impl_delay);
777 pcf8584_put_s0(pcf8584_t *i2c, char data)
779 ddi_acc_handle_t hp = i2c->pcf8584_rhandle;
780 pcf8584_regs_t *rp = &i2c->pcf8584_regs;
783 PCF8584_IMPL_DELAY(i2c->pcf8584_impl_type,
784 i2c->pcf8584_impl_delay);
789 PCF8584_IMPL_DELAY(i2c->pcf8584_impl_type,
790 i2c->pcf8584_impl_delay);
797 pcf8584_get_s0(pcf8584_t *i2c)
799 ddi_acc_handle_t hp = i2c->pcf8584_rhandle;
800 pcf8584_regs_t *rp = &i2c->pcf8584_regs;
804 PCF8584_IMPL_DELAY(i2c->pcf8584_impl_type,
805 i2c->pcf8584_impl_delay);
814 pcf8584_get_s1(pcf8584_t *i2c)
816 ddi_acc_handle_t hp = i2c->pcf8584_rhandle;
817 pcf8584_regs_t *rp = &i2c->pcf8584_regs;
821 PCF8584_IMPL_DELAY(i2c->pcf8584_impl_type,
822 i2c->pcf8584_impl_delay);
835 pcf8584_bbn_ready(pcf8584_t *i2c)
840 s1 = pcf8584_get_s1(i2c);
846 pcf8584_monitor_mode(i2c);
847 pcf8584_put_s1(i2c, S1_STOP);
849 pcf8584_init(i2c);
850 (void) pcf8584_get_s0(i2c);
851 s1 = pcf8584_get_s1(i2c);
855 i2c->pcf8584_name,
856 pcf8584_dip_to_addr(i2c->pcf8584_cur_dip));
862 i2c->pcf8584_name,
863 pcf8584_dip_to_addr(i2c->pcf8584_cur_dip));
869 s1 = pcf8584_get_s1(i2c);
876 pcf8584_error(int status, uint8_t rdwr, pcf8584_t *i2c)
878 int addr = pcf8584_dip_to_addr(i2c->pcf8584_cur_dip);
879 pcf8584_regs_t *rp = &i2c->pcf8584_regs;
884 " addr = 0x%x", i2c->pcf8584_name,
886 pcf8584_init(i2c);
891 " 0x%p addr = 0x%x", i2c->pcf8584_name,
893 pcf8584_init(i2c);
901 pcf8584_put_s1(i2c, S1_STOP);
910 pcf8584_monitor_mode(pcf8584_t *i2c)
912 pcf8584_put_s1(i2c, S1_PIN);
914 pcf8584_put_s0(i2c, MONITOR_ADDRESS);
989 pcf8584_init(pcf8584_t *i2c)
993 pcf8584_put_s1(i2c, S1_PIN);
995 pcf8584_put_s0(i2c, S0_OWN);
997 pcf8584_put_s1(i2c, S1_PIN | S1_ES1);
1005 if (i2c->pcf8584_impl_type == BBC) {
1022 pcf8584_put_s0(i2c, clk_div);
1024 pcf8584_put_s1(i2c, S1_PIN | S1_ESO | S1_ACK);
1032 * on the i2c bus is a 256 byte read from the seprom which takes
1044 pcf8584_setup_regs(dev_info_t *dip, pcf8584_t *i2c)
1061 &i2c->pcf8584_rhandle) != DDI_SUCCESS) {
1067 * If i2c controller is on BBC, then s1 comes before s0.
1069 if (i2c->pcf8584_impl_type == BBC) {
1070 i2c->pcf8584_regs.pcf8584_regs_s0 =
1072 i2c->pcf8584_regs.pcf8584_regs_s1 =
1075 i2c->pcf8584_regs.pcf8584_regs_s0 =
1077 i2c->pcf8584_regs.pcf8584_regs_s1 =
1083 1, (caddr_t *)&i2c->pcf8584_b_reg,
1084 0, 0, &attr, &i2c->pcf8584_b_rhandle) !=
1099 pcf8584_free_regs(pcf8584_t *i2c)
1101 if (i2c->pcf8584_regs.pcf8584_regs_s0 != NULL) {
1102 ddi_regs_map_free(&i2c->pcf8584_rhandle);
1104 if (i2c->pcf8584_b_reg != NULL) {
1105 ddi_regs_map_free(&i2c->pcf8584_b_rhandle);
1144 pcf8584_t *i2c = (pcf8584_t *)arg;
1147 ASSERT(i2c->pcf8584_mode != PCF8584_POLL_MODE);
1150 mutex_enter(&i2c->pcf8584_imutex);
1160 if (i2c->pcf8584_cur_tran == NULL) {
1161 mutex_exit(&i2c->pcf8584_imutex);
1167 s1 = pcf8584_get_s1(i2c);
1169 mutex_exit(&i2c->pcf8584_imutex);
1174 if (pcf8584_process(i2c, s1) == I2C_COMPLETE) {
1175 i2c->pcf8584_tran_state = TRAN_STATE_NULL;
1176 i2c->pcf8584_cur_status = PCF8584_TRANSFER_OVER;
1177 cv_signal(&i2c->pcf8584_icv);
1179 i2c->pcf8584_cur_status = PCF8584_TRANSFER_ON;
1181 mutex_exit(&i2c->pcf8584_imutex);
1191 pcf8584_process(pcf8584_t *i2c, uint8_t s1)
1193 i2c_transfer_t *tp = i2c->pcf8584_cur_tran;
1194 int addr = pcf8584_dip_to_addr(i2c->pcf8584_cur_dip);
1197 ASSERT(i2c->pcf8584_tran_state != TRAN_STATE_NULL);
1199 switch (i2c->pcf8584_tran_state) {
1203 if (pcf8584_error(s1, I2C_RD, i2c) != I2C_SUCCESS) {
1208 i2c->pcf8584_tran_state = TRAN_STATE_START;
1209 pcf8584_put_s0(i2c, DUMMY_DATA);
1213 if (pcf8584_error(s1, I2C_RD, i2c) != I2C_SUCCESS) {
1220 i2c->pcf8584_tran_state =
1227 if (i2c->pcf8584_mode == PCF8584_POLL_MODE)
1228 pcf8584_put_s1(i2c, S1_START2);
1230 pcf8584_put_s1(i2c, S1_START2 | S1_ENI);
1231 pcf8584_put_s0(i2c, addr);
1238 if (pcf8584_error(s1, I2C_WR, i2c) != I2C_SUCCESS) {
1247 pcf8584_put_s1(i2c, S1_STOP);
1254 pcf8584_put_s0(i2c, tp->i2c_wbuf[tp->i2c_wlen -
1263 if (pcf8584_error(s1, I2C_WR, i2c) != I2C_SUCCESS) {
1279 if (i2c->pcf8584_mode == PCF8584_POLL_MODE)
1280 pcf8584_put_s1(i2c, S1_ESO);
1282 pcf8584_put_s1(i2c, S1_ESO | S1_ENI);
1288 dummy_read = pcf8584_get_s0(i2c);
1290 i2c->pcf8584_tran_state = TRAN_STATE_RD;
1296 if (pcf8584_error(s1, I2C_RD, i2c) != I2C_SUCCESS) {
1310 pcf8584_put_s1(i2c, S1_STOP);
1319 if (i2c->pcf8584_mode == PCF8584_POLL_MODE)
1320 pcf8584_put_s1(i2c, S1_ESO);
1322 pcf8584_put_s1(i2c, S1_ESO | S1_ENI);
1326 pcf8584_get_s0(i2c);
1342 if (pcf8584_error(s1, I2C_WR, i2c) != I2C_SUCCESS) {
1348 pcf8584_put_s1(i2c, S1_STOP);
1355 pcf8584_put_s0(i2c, tp->i2c_wbuf[tp->i2c_wlen -
1362 if (i2c->pcf8584_mode == PCF8584_POLL_MODE)
1363 pcf8584_put_s1(i2c, S1_START2);
1365 pcf8584_put_s1(i2c, S1_START2 | S1_ENI);
1366 pcf8584_put_s0(i2c, addr | I2C_READ);
1367 i2c->pcf8584_tran_state =
1392 pcf8584_t *i2c;
1397 i2c = (pcf8584_t *)ddi_get_soft_state(pcf8584_state,
1411 pcf8584_take_over(i2c, dip, tp, &waiter, &saved_mode);
1414 pcf8584_acquire(i2c, dip, tp, B_FALSE);
1415 mutex_enter(&i2c->pcf8584_imutex);
1422 if (i2c->pcf8584_cur_tran != tp) {
1423 mutex_exit(&i2c->pcf8584_imutex);
1428 if (pcf8584_bbn_ready(i2c) != I2C_SUCCESS) {
1430 pcf8584_give_up(i2c, waiter, saved_mode);
1432 mutex_exit(&i2c->pcf8584_imutex);
1433 pcf8584_release(i2c, B_FALSE);
1447 pcf8584_select_bus(i2c);
1449 i2c->pcf8584_tran_state = TRAN_STATE_DUMMY_DATA;
1450 pcf8584_put_s0(i2c, DUMMY_ADDR);
1453 if (i2c->pcf8584_mode == PCF8584_POLL_MODE)
1454 pcf8584_put_s1(i2c, S1_START);
1456 pcf8584_put_s1(i2c, S1_START | S1_ENI);
1463 i2c->pcf8584_cur_status = PCF8584_TRANSFER_ON;
1465 if (i2c->pcf8584_mode == PCF8584_POLL_MODE)
1466 pcf8584_do_polled_io(i2c);
1469 pcf8584_give_up(i2c, waiter, saved_mode);
1471 if (i2c->pcf8584_mode != PCF8584_POLL_MODE)
1472 cv_wait(&i2c->pcf8584_icv, &i2c->pcf8584_imutex);
1473 mutex_exit(&i2c->pcf8584_imutex);
1482 if (i2c->pcf8584_cur_tran == tp)
1483 pcf8584_release(i2c, B_FALSE);
1485 plat_shared_i2c_exit(i2c->pcf8584_dip);
1492 pcf8584_do_polled_io(pcf8584_t *i2c)
1498 s1 = pcf8584_get_s1(i2c);
1500 ASSERT(i2c->pcf8584_cur_tran);
1501 completed = pcf8584_process(i2c, s1);
1506 i2c->pcf8584_cur_status = PCF8584_TRANSFER_OVER;
1515 pcf8584_take_over(pcf8584_t *i2c, dev_info_t *dip, i2c_transfer_t *tp,
1518 mutex_enter(&i2c->pcf8584_imutex);
1519 *saved_mode = i2c->pcf8584_mode;
1520 i2c->pcf8584_mode = PCF8584_POLL_MODE;
1526 if (i2c->pcf8584_busy) {
1527 if (i2c->pcf8584_cur_tran &&
1528 i2c->pcf8584_cur_status == PCF8584_TRANSFER_ON) {
1529 pcf8584_do_polled_io(i2c);
1530 *waiter = &i2c->pcf8584_icv;
1539 pcf8584_acquire(i2c, dip, tp, B_TRUE);
1546 pcf8584_give_up(pcf8584_t *i2c, kcondvar_t *waiter, int saved_mode)
1548 i2c->pcf8584_mode = saved_mode;
1555 pcf8584_release(i2c, B_TRUE);
1559 mutex_exit(&i2c->pcf8584_imutex);