Lines Matching defs:i2c

28  * i2bsc.c is the nexus driver i2c traffic against devices hidden behind the
53 #include <sys/i2c/clients/i2c_client.h>
54 #include <sys/i2c/misc/i2c_svc.h>
55 #include <sys/i2c/misc/i2c_svc_impl.h>
56 #include <sys/i2c/nexus/i2bsc_impl.h>
229 i2bsc_t *i2c;
232 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
234 if ((i2c->i2bsc_attachflags & IMUTEX) != 0) {
235 mutex_destroy(&i2c->i2bsc_imutex);
236 cv_destroy(&i2c->i2bsc_icv);
238 if ((i2c->i2bsc_attachflags & SETUP_REGS) != 0) {
239 i2bsc_free_regs(i2c);
241 if ((i2c->i2bsc_attachflags & NEXUS_REGISTER) != 0) {
244 if ((i2c->i2bsc_attachflags & MINOR_NODE) != 0) {
254 i2bsc_t *i2c;
264 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
266 i2c->majornum = ddi_driver_major(dip);
267 i2c->minornum = instance;
268 i2c->i2bsc_dip = dip;
269 i2c->debug = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
272 (void) snprintf(i2c->i2bsc_name, sizeof (i2c->i2bsc_name),
275 if (i2bsc_setup_regs(i2c) != DDI_SUCCESS) {
279 i2c->i2bsc_attachflags |= SETUP_REGS;
281 mutex_init(&i2c->i2bsc_imutex, NULL, MUTEX_DRIVER,
283 cv_init(&i2c->i2bsc_icv, NULL, CV_DRIVER, NULL);
284 i2c->i2bsc_attachflags |= IMUTEX;
287 i2c->i2bsc_attachflags |= NEXUS_REGISTER;
292 i2c->i2bsc_name);
296 i2c->i2bsc_attachflags |= MINOR_NODE;
302 if (i2bsc_is_firmware_broken(i2c)) {
304 " shutting down my i2c services");
308 i2c->i2bsc_attachflags |= FIRMWARE_ALIVE;
311 * Now see if the BSC chip supports the i2c service we rely upon.
313 (void) i2bsc_discover_capability(i2c);
315 if (i2bsc_notify_max_transfer_size(i2c) == DDI_SUCCESS)
316 i2c->i2bsc_attachflags |= TRANSFER_SZ;
318 i2bsc_trace(i2c, 'A', "i2bsc_doattach", "attachflags %d",
319 i2c->i2bsc_attachflags);
367 i2bsc_t *i2c;
376 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
377 if (i2c == NULL)
383 mutex_enter(&i2c->i2bsc_imutex);
384 if (i2c->i2bsc_open) {
385 mutex_exit(&i2c->i2bsc_imutex);
388 i2c->i2bsc_open = 1;
390 mutex_exit(&i2c->i2bsc_imutex);
400 i2bsc_t *i2c;
409 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
410 if (i2c == NULL)
413 mutex_enter(&i2c->i2bsc_imutex);
414 i2c->i2bsc_open = 0;
415 mutex_exit(&i2c->i2bsc_imutex);
425 i2bsc_t *i2c;
431 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, getminor(dev));
433 if (i2c == NULL)
436 self = (dev_info_t *)i2c->i2bsc_dip;
487 i2bsc_t *i2c;
490 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
492 i2bsc_trace(i2c, 'A', "i2bsc_bus_ctl", "dip/rdip,op/arg"
532 i2bsc_t *i2c;
536 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
538 i2bsc_acquire(i2c, NULL, NULL);
543 * the hold that was placed on the i2c bus, which allows any real
549 i2bsc_t *i2c;
553 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
555 i2bsc_release(i2c);
563 i2bsc_acquire(i2bsc_t *i2c, dev_info_t *dip, i2c_transfer_t *tp)
565 mutex_enter(&i2c->i2bsc_imutex);
566 while (i2c->i2bsc_busy) {
567 cv_wait(&i2c->i2bsc_icv, &i2c->i2bsc_imutex);
569 i2c->i2bsc_busy = 1;
570 i2c->i2bsc_cur_tran = tp;
571 i2c->i2bsc_cur_dip = dip;
572 mutex_exit(&i2c->i2bsc_imutex);
579 i2bsc_release(i2bsc_t *i2c)
581 mutex_enter(&i2c->i2bsc_imutex);
582 i2c->i2bsc_busy = 0;
583 i2c->i2bsc_cur_tran = NULL;
584 cv_signal(&i2c->i2bsc_icv);
585 mutex_exit(&i2c->i2bsc_imutex);
591 i2bsc_t *i2c;
599 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, ddi_get_instance(dip));
601 i2bsc_trace(i2c, 'A', "i2bsc_initchild", "dip/cdip %p/%p", dip, cdip);
625 i2bsc_trace(i2c, 'A', "i2bsc_initchild", "#address-cells = 1"
631 i2bsc_trace(i2c, 'A', "i2bsc_initchild", "#address-cells = 2"
645 i2bsc_trace(i2c, 'A', "i2bsc_initchild", "success(%s)",
654 i2bsc_t *i2c;
657 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, ddi_get_instance(dip));
659 i2bsc_trace(i2c, 'D', "i2bsc_uninitchild", "dip/cdip %p/%p", dip, cdip);
667 i2bsc_trace(i2c, 'D', "i2bsc_uninitchild", "success(%s)",
678 i2bsc_setup_regs(i2bsc_t *i2c)
682 i2c->bscbus_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
683 i2c->bscbus_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
684 i2c->bscbus_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
686 if (ddi_dev_nregs(i2c->i2bsc_dip, &nregs) != DDI_SUCCESS) {
694 if (ddi_regs_map_setup(i2c->i2bsc_dip, 0,
695 (caddr_t *)&i2c->bscbus_regs, 0, 0, &i2c->bscbus_attr,
696 &i2c->bscbus_handle) != DDI_SUCCESS) {
708 i2bsc_free_regs(i2bsc_t *i2c)
710 if (i2c->bscbus_regs != NULL) {
711 ddi_regs_map_free(&i2c->bscbus_handle);
749 static int i2bsc_bscbus_state(i2bsc_t *i2c)
753 retval = ddi_get32(i2c->bscbus_handle,
754 (uint32_t *)I2BSC_NEXUS_ADDR(i2c, EBUS_CMD_SPACE_GENERIC,
756 i2c->bscbus_fault = retval;
761 static void i2bsc_clear_acc_fault(i2bsc_t *i2c)
763 i2bsc_trace(i2c, '@', "i2bsc_clear_acc_fault", "clearing acc fault");
764 ddi_put32(i2c->bscbus_handle,
765 (uint32_t *)I2BSC_NEXUS_ADDR(i2c, EBUS_CMD_SPACE_GENERIC,
770 i2bsc_start_session(i2bsc_t *i2c)
772 i2bsc_trace(i2c, 'S', "i2bsc_start_session", "session started");
773 i2c->bscbus_session_failure = 0;
777 i2bsc_fail_session(i2bsc_t *i2c)
779 i2bsc_trace(i2c, 'S', "i2bsc_fail_session", "session failed");
780 i2c->bscbus_session_failure = 1;
784 i2bsc_end_session(i2bsc_t *i2c)
791 i2bsc_trace(i2c, 'S', "i2bsc_end_session", "session ended with %d",
792 i2c->bscbus_session_failure);
793 return ((i2c->bscbus_session_failure) ? DDI_FAILURE : DDI_SUCCESS);
797 i2bsc_is_firmware_broken(i2bsc_t *i2c)
802 i2bsc_trace(i2c, 'A', "i2bsc_is_firmware_broken", "called");
805 (void) ddi_get8(i2c->bscbus_handle,
806 I2BSC_NEXUS_ADDR(i2c, EBUS_CMD_SPACE_I2C,
808 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS) {
809 i2bsc_clear_acc_fault(i2c);
815 i2bsc_trace(i2c, 'A', "i2bsc_is_firmware_broken",
828 i2bsc_trace(i2c, 'A', "i2bsc_is_firmware_broken", "%d read fails",
834 i2bsc_put8(i2bsc_t *i2c, uint8_t space, uint8_t index, uint8_t value)
838 i2bsc_trace(i2c, '@', "i2bsc_put8", "(space,index)<-val (%d,%d)<-%d",
841 i2bsc_clear_acc_fault(i2c);
848 if (i2c->bscbus_session_failure)
852 ddi_put8(i2c->bscbus_handle,
853 I2BSC_NEXUS_ADDR(i2c, space, index), value);
854 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS) {
855 i2bsc_clear_acc_fault(i2c);
860 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
861 i2bsc_fail_session(i2c);
863 i2bsc_trace(i2c, '@', "i2bsc_put8", "tried %d time(s)",
868 i2bsc_get8(i2bsc_t *i2c, uint8_t space, uint8_t index)
873 i2bsc_clear_acc_fault(i2c);
880 if (i2c->bscbus_session_failure)
884 value = ddi_get8(i2c->bscbus_handle,
885 I2BSC_NEXUS_ADDR(i2c, space, index));
886 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS) {
887 i2bsc_clear_acc_fault(i2c);
892 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
893 i2bsc_fail_session(i2c);
895 i2bsc_trace(i2c, '@', "i2bsc_get8", "tried %d time(s)",
898 i2bsc_trace(i2c, '@', "i2bsc_get8", "(space,index)->val (%d,%d)->%d",
904 i2bsc_put8_once(i2bsc_t *i2c, uint8_t space, uint8_t index, uint8_t value)
906 i2bsc_trace(i2c, '@', "i2bsc_put8_once",
909 i2bsc_clear_acc_fault(i2c);
911 ddi_put8(i2c->bscbus_handle,
912 I2BSC_NEXUS_ADDR(i2c, space, index), value);
914 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
915 i2bsc_fail_session(i2c);
919 i2bsc_get8_once(i2bsc_t *i2c, uint8_t space, uint8_t index)
923 i2bsc_clear_acc_fault(i2c);
925 value = ddi_get8(i2c->bscbus_handle,
926 I2BSC_NEXUS_ADDR(i2c, space, index));
928 if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
929 i2bsc_fail_session(i2c);
931 i2bsc_trace(i2c, '@', "i2bsc_get8_once",
938 i2bsc_notify_max_transfer_size(i2bsc_t *i2c)
941 * If the underlying hardware does not support the i2c service and
945 if (i2c->i2c_proxy_support == 0)
948 i2bsc_start_session(i2c);
950 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_MAX_TRANSFER_SZ,
953 if (i2bsc_end_session(i2c) != DDI_SUCCESS)
961 * driver requires. If it does not, i2c transactions will abort with
965 i2bsc_discover_capability(i2bsc_t *i2c)
967 i2bsc_start_session(i2c);
969 i2c->i2c_proxy_support = i2bsc_get8(i2c, EBUS_CMD_SPACE_GENERIC,
971 i2c->i2c_proxy_support &= EBUS_CAP0_I2C_PROXY;
973 if (i2bsc_end_session(i2c) != DDI_SUCCESS)
980 i2bsc_upload_preamble(i2bsc_t *i2c, i2c_transfer_t *tp)
985 ppvt = ddi_get_parent_data(i2c->i2bsc_cur_dip);
987 /* Get a lock on the i2c devices owned by the microcontroller */
988 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_TRANSACTION_LOCK, 1);
989 if (!i2bsc_get8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_TRANSACTION_LOCK)) {
991 * i2c client driver must timeout retry, NOT this nexus
994 i2bsc_trace(i2c, 'U', "i2bsc_upload_preamble",
999 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_BUS_ADDRESS,
1008 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_CLIENT_ADDRESS,
1011 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_TRANSFER_TYPE,
1027 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_WR_RD_BOUNDARY, wr_rd);
1035 * Description This function runs the i2c transfer protocol down to the
1043 i2bsc_upload(i2bsc_t *i2c, i2c_transfer_t *tp)
1059 i2bsc_start_session(i2c);
1060 if (i2bsc_upload_preamble(i2c, tp) != I2C_SUCCESS)
1062 if (i2bsc_end_session(i2c) != DDI_SUCCESS)
1067 i2bsc_put8_once(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_DATA_INOUT,
1069 if (i2bsc_bscbus_state(i2c) == DDI_SUCCESS) {
1074 i2bsc_trace(i2c, 'T', "i2bsc_upload", "write failed");
1082 i2bsc_get8_once(i2c, EBUS_CMD_SPACE_I2C,
1084 if (i2bsc_bscbus_state(i2c) == DDI_SUCCESS) {
1089 i2bsc_trace(i2c, 'T', "i2bsc_upload", "read failed");
1094 i2bsc_start_session(i2c);
1102 i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_RESIDUAL_DATA, residual);
1103 res = i2bsc_get8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_RESULT);
1104 if (i2bsc_end_session(i2c) != DDI_SUCCESS)
1118 i2bsc_trace(i2c, 'T', "i2bsc_upload", "EBUS_I2C_FAILURE"
1140 i2bsc_safe_upload(i2bsc_t *i2c, i2c_transfer_t *tp)
1145 i2bsc_trace(i2c, 'T', "i2bsc_safe_upload", "Transaction %s",
1154 return (i2bsc_upload(i2c, tp));
1157 result = i2bsc_upload(i2c, tp);
1163 i2bsc_trace(i2c, 'T', "i2bsc_safe_upload",
1167 i2bsc_trace(i2c, 'T', "i2bsc_safe_upload",
1173 i2bsc_trace(i2c, 'T', "i2bsc_safe_upload", "Exiting on %d", result);
1180 * Description This is the entry-point that clients use via the Solaris i2c
1181 * framework. It kicks off the servicing of i2c transfer requests.
1186 i2bsc_t *i2c;
1188 i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state,
1191 i2bsc_acquire(i2c, dip, tp);
1197 i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Transaction i2c_version/flags"
1199 i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Transaction buffer rlen/wlen"
1201 i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Transaction ptrs wbuf/rbuf"
1204 if (i2c->i2c_proxy_support)
1205 (void) i2bsc_safe_upload(i2c, tp);
1209 i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Residual writes/reads"
1211 i2bsc_trace(i2c, 'T', "i2bsc_transfer", "i2c_result"
1214 i2bsc_release(i2c);