void pmic_se1i_handler(void) { TRACE_MSG0(REMOVE_TCD, "--"); pmic_otg_wakeup(); #if 0 #if 1 t_sensor_bits sense_bits; if (pmic_get_sensors(&sense_bits)) { printk(KERN_INFO "%s: pmic_get_sensors() failed\n", __FUNCTION__); return; } TRACE_MSG1(REMOVE_TCD, "MC13783 EVENT: se1: %d", sense_bits.sense_se1s); otg_event(tcd_instance->otg, (sense_bits.sense_se1s ? SE1_DET : SE1_DET_), REMOVE_TCD, "MC13783 SE1"); #else otg_event(tcd_instance->otg, (pmic_check_sense(sense_se1s) ? SE1_DET : SE1_DET_), REMOVE_TCD, "MC13783 SE1"); #endif #endif }
void pmic_idi_handler(void) { TRACE_MSG0(REMOVE_TCD, "--"); pmic_otg_wakeup(); #if 0 #if 1 t_sensor_bits sense_bits; if (pmic_get_sensors(&sense_bits)) { printk(KERN_INFO "%s: pmic_get_sensors() failed\n", __FUNCTION__); return; } TRACE_MSG2(REMOVE_TCD, "MC13783 EVENT: IDGNDS: %d IDFLOATS: %d", sense_bits.sense_id_gnds, sense_bits.sense_id_floats); otg_event(tcd_instance->otg, (sense_bits.sense_id_gnds ? ID_GND : ID_GND_) | (sense_bits.sense_id_floats ? ID_FLOAT : ID_FLOAT_), REMOVE_TCD, "MC13783 IDI"); #else otg_event(tcd_instance->otg, (pmic_check_sense(sense_id_gnds) ? ID_GND : ID_GND_) | (pmic_check_sense(sense_id_floats) ? ID_FLOAT : ID_FLOAT_), REMOVE_TCD, "MC13783 IDI"); #endif #endif }
/*! * mxc_gptcr_timer_int_hndlr() - timer interrupt * @param irq * @param dev_id * @param regs */ irqreturn_t mxc_gptcr_timer_int_hndlr (int irq, void *dev_id, struct pt_regs *regs) { u32 gptsr = *_reg_GPT_GPTSR; *_reg_GPT_GPTIR &= ~(0x04); if (gptsr & (0x01 << 2)){ TRACE_MSG7(OCD, "cnt: %08x match: %08x gptsr: %08x GPTCNT: %08x GPTCR: %08x GPTSR: %08x GPTOCR3: %08x\n", mxc_gptcr_ticks_set, mxc_gptcr_match_set, gptsr, *_reg_GPT_GPTCNT, *_reg_GPT_GPTCR, *_reg_GPT_GPTSR, *_reg_GPT_GPTOCR3); *_reg_GPT_GPTCR &= ~(0x7 << 26); *_reg_GPT_GPTOCR3 = 0; TRACE_MSG0(OCD, "OCM3"); TRACE_MSG1(OCD, "active: %x", mxc_gptcr_active); if (mxc_gptcr_active) { TRACE_MSG0(OCD, "calling otg_event"); mxc_gptcr_active = 0; otg_event(ocd_instance->otg, TMOUT, OCD, "TMOUT"); } else { TRACE_MSG0(OCD, "skipping otg_event"); } *_reg_GPT_GPTSR |= 0x4; return IRQ_HANDLED; } if (!mxc_shared_int) *_reg_GPT_GPTIR |= 0x4; return IRQ_NONE; }
/*! * l26_ocd_init() - used to initialize/enable or disable the tcd driver * @param otg * @param flag */ static void l26_ocd_init(struct otg_instance *otg, u8 flag) { struct ocd_instance *ocd = otg->ocd; TRACE_MSG0(ocd->TAG, "--"); switch (flag) { case SET: TRACE_MSG0(ocd->TAG, "FS_OCD_EN SET"); //l26_init(); otg_event(otg, TCD_OK | ID_FLOAT, otg->ocd->TAG, "OCD_OK"); break; case RESET: //l26_exit(); TRACE_MSG0(ocd->TAG, "FS_OCD_EN RESET"); otg_event(otg, TCD_OK | ID_FLOAT, otg->ocd->TAG, "OCD_OK"); break; } }
/*! pmic_otg_event_bh - pmic otg event handler * @param data - otg instance */ void pmic_otg_event_bh(void *data) { struct otg_instance *otg = (struct otg_instance *) data; otg_current_t inputs; t_sensor_bits sense_bits; static BOOL force = TRUE; static otg_current_t inputs_saved = 0; if (pmic_get_sensors(&sense_bits)) { printk(KERN_INFO "%s: pmic_get_sensors() failed\n", __FUNCTION__); return; } TRACE_MSG6(REMOVE_TCD, "usb4v4s%c usb2v0s%c usb0v8s:%c id_gnds%c id_floats%c id_se1s%c", sense_bits.sense_usb4v4s ? ' ' : '/', sense_bits.sense_usb2v0s ? ' ' : '/', sense_bits.sense_usb0v8s ? ' ' : '/', sense_bits.sense_id_gnds ? ' ' : '/', sense_bits.sense_id_floats ? ' ' : '/', sense_bits.sense_se1s ? ' ' : '/'); inputs = (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) | (sense_bits. sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) | (sense_bits.sense_usb0v8s ? B_SESS_END_ : B_SESS_END) | (sense_bits. sense_id_gnds ? ID_GND : ID_GND_) | (sense_bits.sense_id_floats ? ID_FLOAT : ID_FLOAT_) | (sense_bits. sense_se1s ? SE1_DET : SE1_DET_) | (det_dp_hi ? DP_HIGH : DP_HIGH_) | (det_dm_hi ? DM_HIGH : DM_HIGH_); // printk(KERN_INFO" inputs: %8X\n", inputs); TRACE_MSG4(REMOVE_TCD, "MC13783 EVENT: sense_bits: %8x otg inputs: %8x saved: %x diff: %x", sense_bits.sense_se1s, inputs, inputs_saved, inputs ^ inputs_saved); RETURN_UNLESS(force || (inputs ^ inputs_saved)); inputs_saved = inputs; otg_event(REMOVE_tcd_instance->otg, inputs, REMOVE_TCD, "PMIC OTG EVENT"); // gpio_config_int_en(2, 17, TRUE); // gpio_config_int_en(2, 16, TRUE); // gpio_clear_int (2, 17); // gpio_clear_int (2, 16); }
/*! * mxc_ocd_init() - used to initialize/enable or disable the tcd driver * @param otg * @param flag */ void mxc_ocd_init(struct otg_instance *otg, u8 flag) { TRACE_MSG0(otg->ocd->TAG, "--"); switch (flag) { case SET: TRACE_MSG0(otg->ocd->TAG, "FS_otg->ocd->TAG_EN SET"); mxc_init(otg); break; case RESET: mxc_exit(otg); TRACE_MSG0(otg->ocd->TAG, "FS_otg->ocd->TAG_EN RESET"); break; } otg_event(otg, OCD_OK, otg->ocd->TAG, "MX21 OK"); }
/*! * mxc_pmic_usbi_handler() - event handler * * * */ void pmic_usbi_handler(void) { TRACE_MSG0(REMOVE_TCD, "--"); pmic_otg_wakeup(); #if 0 #if 1 t_sensor_bits sense_bits; if (pmic_get_sensors(&sense_bits)) { printk(KERN_INFO "%s: pmic_get_sensors() failed\n", __FUNCTION__); return; } TRACE_MSG3(REMOVE_TCD, "MC13783 EVENT: 4V4S: %d 2V0S: %d 0V8S: %d", sense_bits.sense_usb4v4s, sense_bits.sense_usb2v0s, sense_bits.sense_usb0v8s); otg_event(tcd_instance->otg, (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) | (sense_bits. sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) | (sense_bits.sense_usb0v8s ? B_SESS_END : B_SESS_END_), REMOVE_TCD, "MC13783 USBI"); #else otg_event(tcd_instance->otg, (pmic_check_sense(sense_usb4v4s) ? VBUS_VLD : VBUS_VLD_) | (pmic_check_sense(sense_usb4v4s) ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) | (pmic_check_sense(sense_usb0v8s) ? B_SESS_END : B_SESS_END_), REMOVE_TCD, "MC13783 USBI"); #endif #endif }
/*! mxc_pmic_tcd_init() - used to enable mc13783 * @param otg - otg instance pointer * @param flag - * */ void mxc_pmic_tcd_init(struct otg_instance *otg, u8 flag) { struct tcd_instance *tcd = otg->tcd; switch (flag) { case SET: case PULSE: TRACE_MSG0(tcd->TAG, "SET/PULSE"); break; case RESET: TRACE_MSG0(tcd->TAG, "RESET"); break; } pmic_otg_wakeup(); otg_event (otg, OCD_OK, otg->tcd->TAG, "MC13783 OK"); }
void mxc_hrt_callback (unsigned long arg) { TRACE_MSG1(OCD, "checking active: %d", mxc_hr_active); RETURN_UNLESS(mxc_hr_active); mxc_hr_active = FALSE; TRACE_MSG1(OCD, "resetting active: %d", mxc_hr_active); if (mxc_hr_usec_set >= 1000000) { //if requested period is in the range of 1 sec hr_timer.expires = jiffies + ((mxc_hr_usec_set/1000000)*mxc_hr_jiffy_per_sec); hr_timer.arch_cycle_expires = get_arch_cycles(jiffies); hr_timer.function = mxc_hrt_callback; } else { hr_timer.expires = jiffies; hr_timer.arch_cycle_expires = get_arch_cycles(jiffies); if (mxc_hr_usec_set < 100) { TRACE_MSG1(OCD, "usec: %d set to minimum 100", mxc_hr_usec_set); mxc_hr_usec_set = 100; } hr_timer.arch_cycle_expires += nsec_to_arch_cycle(mxc_hr_usec_set * 1000); //hr_timer.arch_cycle_expires += nsec_to_arch_cycle(100 * 1000 * 1000); while (hr_timer.arch_cycle_expires >= arch_cycles_per_jiffy) { hr_timer.expires++; hr_timer.arch_cycle_expires -= arch_cycles_per_jiffy; } } //end of else TRACE_MSG3 (OCD, "usec: %d expires: %8u arch_cycle_expires: %8u", mxc_hr_usec_set, hr_timer.expires, hr_timer.arch_cycle_expires); otg_event(ocd_instance->otg, TMOUT, OCD, "TMOUT"); // add_timer(&hr_timer); }
void mc13783_otg_event_bh (void *arg) { u64 inputs; t_sense_bits sense_bits; static BOOL force = TRUE; static u64 inputs_saved = 0; // Note: power_ic has USB4V4S labelled as USBI, which is incorrect // Get the sense bits, return if any fail to be read. if ( (sense_bits.sense_usb4v4s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_USBI)) < 0) { printk(KERN_INFO"%s: mc13783_get_sense() usb4v4s failed\n", __FUNCTION__); return; } if ( (sense_bits.sense_usb2v0s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_USB2V0S)) < 0) { printk(KERN_INFO"%s: mc13783_get_sense() usb2v0s failed\n", __FUNCTION__); return; } if ( (sense_bits.sense_usb0v8s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_USB0V8S)) < 0) { printk(KERN_INFO"%s: mc13783_get_sense() usb0v8s failed\n", __FUNCTION__); return; } if ( (sense_bits.sense_id_floats = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_ID_FLOAT)) < 0) { printk(KERN_INFO"%s: mc13783_get_sense() id_floats failed\n", __FUNCTION__); return; } if ( (sense_bits.sense_id_gnds = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_ID_GROUND)) < 0) { printk(KERN_INFO"%s: mc13783_get_sense() id_gnds failed\n", __FUNCTION__); return; } if ( (sense_bits.sense_se1s = power_ic_event_sense_read(POWER_IC_EVENT_ATLAS_SE1I)) < 0) { printk(KERN_INFO"%s: mc13783_get_sense() se1s failed\n", __FUNCTION__); return; } // Factory cable check meant for USB B device only. If IDGNDS is True // adjust the value of IDGNDS to be False, so the state machine thinks it's a // traditional device and not a Dual role device. #ifdef CONFIG_OTG_USB_PERIPHERAL if ( sense_bits.sense_id_gnds ) { sense_bits.sense_id_gnds = FALSE; TRACE_MSG0(TCD, "Factory Cable detected and IDGND modified to false"); // printk("Factory Cable detected and IDGND modified to false\n"); } #endif inputs = (sense_bits.sense_usb4v4s ? VBUS_VLD : VBUS_VLD_) | (sense_bits.sense_usb2v0s ? (B_SESS_VLD | A_SESS_VLD) : (B_SESS_VLD_ | A_SESS_VLD_)) | (sense_bits.sense_usb0v8s ? B_SESS_END_ : B_SESS_END) | (sense_bits.sense_id_gnds ? ID_GND : ID_GND_) | (sense_bits.sense_id_floats ? ID_FLOAT : ID_FLOAT_) | (sense_bits.sense_se1s ? SE1_DET : SE1_DET_) | (det_dp_hi ? DP_HIGH : DP_HIGH_) | (det_dm_hi ? DM_HIGH : DM_HIGH_); TRACE_MSG4(TCD, "MC13783 EVENT: sense_bits: %8x otg inputs: %8x saved: %x diff: %x", sense_bits.sense_se1s, inputs, inputs_saved, inputs ^ inputs_saved); RETURN_UNLESS(force || (inputs ^ inputs_saved)); inputs_saved = inputs; otg_event(tcd_instance->otg, inputs, TCD, "MC13783 OTG EVENT"); }
/*! * l26_ocd_start_timer() - start a timer for otg state machine * Set or reset timer to interrupt in number of uS (micro-seconds). * * @param otg * @param usec */ int l26_ocd_start_timer(struct otg_instance *otg, int usec) { otg_event(otg, TMOUT, otg->ocd->TAG, "l26 Timer"); return 0; }
/*! * otg_message_ioctl_internal() - ioctl call * @param cmd ioctl command. * @param arg ioctl arguement. * @return non-zero for error. */ int otg_message_ioctl_internal(unsigned int cmd, unsigned long arg) { int i; int len; int flag; struct otg_admin_command admin_command; struct otg_status_update status_update; struct otg_firmware_info firmware_info; struct otg_state otg_state; struct otg_test otg_test; struct otg_ioctl_name *otg_ioctl_name; static char func_buf[32]; char *sp, *dp; char *name; //printk(KERN_INFO"%s: cmd: %08x %08x\n", __FUNCTION__, cmd, _IOC_NR(cmd)); //TRACE_MSG2(CORE, "cmd: %08x %08x", cmd, _IOC_NR(cmd)); switch (_IOC_DIR(cmd)) { case _IOC_NONE: switch (_IOC_NR(cmd)) { } break; case _IOC_WRITE: switch (_IOC_NR(cmd)) { case _IOC_NR(OTGADMIN_SET_FUNCTION): TRACE_MSG0(CORE, "OTGADMIN_SET_FUNCTION"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); memset(&admin_command, 0x41, sizeof(struct otg_admin_command)); RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd))); len = sizeof(mesg_otg_instance->function_name); admin_command.string[len] = '\0'; //TRACE_MSG1(CORE, "Setting function: \"%s\"", mesg_otg_instance->function_name); strncpy(mesg_otg_instance->function_name, admin_command.string, len); mesg_otg_instance->function_name[len-1] = '\0'; return 0; case _IOC_NR(OTGADMIN_SET_SERIAL): TRACE_MSG0(CORE, "OTGADMIN_SET_SERIAL"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd))); admin_command.string[sizeof(admin_command.string) - 1] = '\0'; //printk(KERN_INFO"%s: string: %s\n", __FUNCTION__, admin_command.string); for (sp = admin_command.string, dp = mesg_otg_instance->serial_number, i = 0; *sp && (i < (sizeof(admin_command.string) - 1)); i++, sp++) if (isxdigit(*sp)) *dp++ = toupper(*sp); *sp = '\0'; //TRACE_MSG1(CORE, "serial_number: %s", mesg_otg_instance->serial_number); printk(KERN_INFO"%s: serial: %s\n", __FUNCTION__, mesg_otg_instance->serial_number); return 0; case _IOC_NR(OTGADMIN_SET_INFO): TRACE_MSG0(CORE, "OTGADMIN_SET_INFO"); memset(&firmware_info, 0x41, sizeof(firmware_info)); RETURN_EINVAL_IF(copy_from_user(&firmware_info, (void *)arg, _IOC_SIZE(cmd))); return otg_mesg_set_firmware_info(&firmware_info); return 0; case _IOC_NR(OTGADMIN_SET_STATE): //TRACE_MSG0(CORE, "OTGADMIN_XXX_STATE"); RETURN_EINVAL_IF(copy_from_user(&otg_state, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loading); //TRACE_MSG0(CORE, "OTGADMIN_SET_STATE"); RETURN_EINVAL_UNLESS (otg_state.state < otg_firmware_loading->number_of_states); memcpy(otg_firmware_loading->otg_states + otg_state.state, &otg_state, sizeof(otg_state)); return 0; case _IOC_NR(OTGADMIN_SET_TEST): //TRACE_MSG0(CORE, "OTGADMIN_GET/SET"); RETURN_EINVAL_IF(copy_from_user(&otg_test, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loading); //TRACE_MSG1(CORE, "OTGADMIN_SET_TEST : %d", otg_test.test); RETURN_EINVAL_UNLESS (otg_test.test < otg_firmware_loading->number_of_tests); memcpy(otg_firmware_loading->otg_tests + otg_test.test, &otg_test, sizeof(otg_test)); return 0; } break; case _IOC_READ: switch (_IOC_NR(cmd)) { case _IOC_NR(OTGADMIN_GET_FUNCTION): TRACE_MSG0(CORE, "OTGADMIN_GET_FUNCTION"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); RETURN_EINVAL_IF(copy_from_user(&admin_command, (void *)arg, _IOC_SIZE(cmd))); name = otg_usbd_ops->function_name(admin_command.n); admin_command.string[0] = '\0'; if (name) strncat(admin_command.string, name, sizeof(admin_command.string)); RETURN_EINVAL_IF(copy_to_user((void *)arg, &admin_command, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_GET_SERIAL): TRACE_MSG0(CORE, "OTGADMIN_GET_SERIAL"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); strncpy(admin_command.string, mesg_otg_instance->serial_number, sizeof(admin_command.string)); admin_command.string[sizeof(admin_command.string) - 1] = '\0'; RETURN_EINVAL_IF(copy_to_user((void *)arg, &admin_command, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_STATUS): //TRACE_MSG0(CORE, "OTGADMIN_STATUS"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); memset(&status_update, 0, sizeof(struct otg_status_update)); otg_mesg_get_status_update(&status_update); RETURN_EINVAL_IF(copy_to_user((void *)arg, &status_update, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_GET_INFO): TRACE_MSG0(CORE, "OTGADMIN_GET_INFO"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); otg_mesg_get_firmware_info(&firmware_info); RETURN_EINVAL_IF(copy_to_user((void *)arg, &firmware_info, _IOC_SIZE(cmd))); //TRACE_MSG0(CORE, "OTGADMIN_GET_INFO: finished"); return 0; case _IOC_NR(OTGADMIN_GET_STATE): //TRACE_MSG0(CORE, "OTGADMIN_XXX_STATE"); RETURN_EINVAL_IF(copy_from_user(&otg_state, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loaded); //TRACE_MSG0(CORE, "OTGADMIN_GET_STATE"); RETURN_EINVAL_UNLESS (otg_state.state < otg_firmware_loaded->number_of_states); memcpy(&otg_state, otg_firmware_loaded->otg_states + otg_state.state, sizeof(otg_state)); RETURN_EINVAL_IF(copy_to_user((void *)arg, &otg_state, _IOC_SIZE(cmd))); return 0; case _IOC_NR(OTGADMIN_GET_TEST): //TRACE_MSG0(CORE, "OTGADMIN_GET/SET"); RETURN_EINVAL_IF(copy_from_user(&otg_test, (void *)arg, _IOC_SIZE(cmd))); RETURN_EINVAL_UNLESS(otg_firmware_loaded); //TRACE_MSG1(CORE, "OTGADMIN_GET_TEST: %d", otg_test.test); RETURN_EINVAL_UNLESS (otg_test.test < otg_firmware_loaded->number_of_tests); memcpy(&otg_test, otg_firmware_loaded->otg_tests + otg_test.test, sizeof(otg_test)); RETURN_EINVAL_IF(copy_to_user((void *)arg, &otg_test, _IOC_SIZE(cmd))); return 0; } break; } TRACE_MSG0(CORE, "OTGADMIN_"); RETURN_EINVAL_UNLESS(otg_firmware_loaded); for (otg_ioctl_name = otg_ioctl_names; otg_ioctl_name && otg_ioctl_name->cmd; otg_ioctl_name++) { //TRACE_MSG4(CORE, "lookup: %04x %04x %08x %08x", // _IOC_NR(cmd), _IOC_NR(otg_ioctl_name->cmd), cmd, otg_ioctl_name->cmd); BREAK_IF(_IOC_NR(otg_ioctl_name->cmd) == _IOC_NR(cmd)); } //TRACE_MSG3(CORE, "checking %d %08x %08x", _IOC_NR(cmd), otg_ioctl_name->cmd, cmd); RETURN_EINVAL_UNLESS(otg_ioctl_name->cmd); __get_user(flag, (int *)arg); //TRACE_MSG3(CORE, "%s %08x flag: %d", otg_ioctl_name->name, otg_ioctl_name->set, flag); otg_event (mesg_otg_instance, flag ? otg_ioctl_name->set : _NOT(otg_ioctl_name->set), CORE, otg_ioctl_name->name); return 0; }