static void musb_id_pin_work(struct work_struct *data) { u8 devctl = 0; unsigned long flags; spin_lock_irqsave(&mtk_musb->lock, flags); musb_generic_disable(mtk_musb); spin_unlock_irqrestore(&mtk_musb->lock, flags); down(&mtk_musb->musb_lock); DBG(0, "work start, is_host=%d\n", mtk_musb->is_host); if(mtk_musb->in_ipo_off) { DBG(0, "do nothing due to in_ipo_off\n"); goto out; } mtk_musb ->is_host = musb_is_host(); DBG(0,"musb is as %s\n",mtk_musb->is_host?"host":"device"); switch_set_state((struct switch_dev *)&otg_state, mtk_musb->is_host); if (mtk_musb->is_host) { //setup fifo for host mode ep_config_from_table_for_host(mtk_musb); wake_lock(&mtk_musb->usb_lock); musb_platform_set_vbus(mtk_musb, 1); /* for no VBUS sensing IP*/ #if 1 /* wait VBUS ready */ msleep(100); /* clear session*/ devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL); musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (devctl&(~MUSB_DEVCTL_SESSION))); /* USB MAC OFF*/ /* VBUSVALID=0, AVALID=0, BVALID=0, SESSEND=1, IDDIG=X */ USBPHY_SET8(0x6c, 0x10); USBPHY_CLR8(0x6c, 0x2e); USBPHY_SET8(0x6d, 0x3e); DBG(0,"force PHY to idle, 0x6d=%x, 0x6c=%x\n",USBPHY_READ8(0x6d), USBPHY_READ8(0x6c)); /* wait */ msleep(5); /* restart session */ devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL); musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (devctl| MUSB_DEVCTL_SESSION)); /* USB MAC ONand Host Mode*/ /* VBUSVALID=1, AVALID=1, BVALID=1, SESSEND=0, IDDIG=0 */ USBPHY_CLR8(0x6c, 0x10); USBPHY_SET8(0x6c, 0x2c); USBPHY_SET8(0x6d, 0x3e); DBG(0,"force PHY to host mode, 0x6d=%x, 0x6c=%x\n",USBPHY_READ8(0x6d), USBPHY_READ8(0x6c)); #endif musb_start(mtk_musb); MUSB_HST_MODE(mtk_musb); switch_int_to_device(mtk_musb); } else { DBG(0,"devctl is %x\n",musb_readb(mtk_musb->mregs,MUSB_DEVCTL)); musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,0); if (wake_lock_active(&mtk_musb->usb_lock)) wake_unlock(&mtk_musb->usb_lock); musb_platform_set_vbus(mtk_musb, 0); /* for no VBUS sensing IP */ #if 1 /* USB MAC OFF*/ /* VBUSVALID=0, AVALID=0, BVALID=0, SESSEND=1, IDDIG=X */ USBPHY_SET8(0x6c, 0x10); USBPHY_CLR8(0x6c, 0x2e); USBPHY_SET8(0x6d, 0x3e); DBG(0,"force PHY to idle, 0x6d=%x, 0x6c=%x\n", USBPHY_READ8(0x6d), USBPHY_READ8(0x6c)); #endif musb_stop(mtk_musb); //ALPS00849138 mtk_musb->xceiv->state = OTG_STATE_B_IDLE; MUSB_DEV_MODE(mtk_musb); switch_int_to_host(mtk_musb); } out: DBG(0, "work end, is_host=%d\n", mtk_musb->is_host); up(&mtk_musb->musb_lock); }
static void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct pm8058_led_data *ldata; int *pduties; int id, mode; int lut_flag; int milliamps; int enable = 0; ldata = container_of(led_cdev, struct pm8058_led_data, ldev); pwm_disable(ldata->pwm_led); cancel_delayed_work_sync(&ldata->led_delayed_work); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); brightness = (brightness > LED_FULL) ? LED_FULL : brightness; brightness = (brightness < LED_OFF) ? LED_OFF : brightness; LED_INFO_LOG("%s: bank %d brightness %d +\n", __func__, ldata->bank, brightness); enable = (brightness) ? 1 : 0; if (strcmp(ldata->ldev.name, "charming-led") == 0) charming_led_enable(enable); lut_flag = ldata->lut_flag & ~(PM_PWM_LUT_LOOP | PM_PWM_LUT_REVERSE); if (brightness) { milliamps = (ldata->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ? ldata->out_current * brightness / LED_FULL : ldata->out_current; pm8058_pwm_config_led(ldata->pwm_led, id, mode, milliamps); if (ldata->flags & PM8058_LED_LTU_EN) { pduties = &duties[ldata->start_index]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index, ldata->duites_size, 0, 0, lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_lut_enable(ldata->pwm_led, 1); } else { pwm_config(ldata->pwm_led, 64000, 64000); pwm_enable(ldata->pwm_led); } } else { if (ldata->flags & PM8058_LED_LTU_EN) { wake_lock(&pmic_led_wake_lock); pduties = &duties[ldata->start_index + ldata->duites_size]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index + ldata->duites_size, ldata->duites_size, 0, 0, lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 1); queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(ldata->duty_time_ms * ldata->duty_time_ms)); LED_INFO_LOG("%s: bank %d fade out brightness %d -\n", __func__, ldata->bank, brightness); return; } else pwm_disable(ldata->pwm_led); pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } LED_INFO_LOG("%s: bank %d brightness %d -\n", __func__, ldata->bank, brightness); }
static void smd_tty_notify(void *priv, unsigned event) { struct smd_tty_info *info = priv; struct tty_struct *tty; unsigned long flags; switch (event) { case SMD_EVENT_DATA: spin_lock_irqsave(&info->reset_lock, flags); if (!info->is_open) { spin_unlock_irqrestore(&info->reset_lock, flags); break; } spin_unlock_irqrestore(&info->reset_lock, flags); /* There may be clients (tty framework) that are blocked * waiting for space to write data, so if a possible read * interrupt came in wake anyone waiting and disable the * interrupts */ if (smd_write_avail(info->ch)) { smd_disable_read_intr(info->ch); tty = tty_port_tty_get(&info->port); if (tty) wake_up_interruptible(&tty->write_wait); tty_kref_put(tty); } spin_lock_irqsave(&info->ra_lock, flags); if (smd_read_avail(info->ch)) { wake_lock(&info->ra_wake_lock); tasklet_hi_schedule(&info->tty_tsklt); } spin_unlock_irqrestore(&info->ra_lock, flags); break; case SMD_EVENT_OPEN: spin_lock_irqsave(&info->reset_lock, flags); info->in_reset = 0; info->in_reset_updated = 1; info->is_open = 1; wake_up_interruptible(&info->ch_opened_wait_queue); spin_unlock_irqrestore(&info->reset_lock, flags); break; case SMD_EVENT_CLOSE: spin_lock_irqsave(&info->reset_lock, flags); info->in_reset = 1; info->in_reset_updated = 1; info->is_open = 0; wake_up_interruptible(&info->ch_opened_wait_queue); spin_unlock_irqrestore(&info->reset_lock, flags); /* schedule task to send TTY_BREAK */ tasklet_hi_schedule(&info->tty_tsklt); tty = tty_port_tty_get(&info->port); if (tty->index == LOOPBACK_IDX) schedule_delayed_work(&loopback_work, msecs_to_jiffies(1000)); tty_kref_put(tty); break; #ifdef CONFIG_LGE_USES_SMD_DS_TTY /* */ case SMD_EVENT_REOPEN_READY: /* smd channel is closed completely */ spin_lock_irqsave(&info->reset_lock, flags); info->in_reset = 1; info->in_reset_updated = 1; info->is_open = 0; wake_up_interruptible(&info->ch_opened_wait_queue); spin_unlock_irqrestore(&info->reset_lock, flags); break; #endif } }
static inline void lock_pm_wake(struct modem_link_pm *pm) { if (!wake_lock_active(&pm->wlock)) wake_lock(&pm->wlock); }
/* * Internal function. Schedule delayed work in the MMC work queue. */ static int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) { wake_lock(&mmc_delayed_work_wake_lock); return queue_delayed_work(workqueue, work, delay); }
/*---------------------------------------------------------- * fcsmd_open *---------------------------------------------------------*/ static int fcsmd_open (struct inode *inode, struct file *filp) { wake_lock(&fcsmd_wakelock); return 0; }
static int snddev_icodec_open_rx(struct snddev_icodec_state *icodec) { int trc, err; int smps_mode = PMAPP_SMPS_MODE_VOTE_PWM; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv; struct lpa_codec_config lpa_config; wake_lock(&drv->rx_idlelock); if ((icodec->data->acdb_id == ACDB_ID_HEADSET_SPKR_MONO) || (icodec->data->acdb_id == ACDB_ID_HEADSET_SPKR_STEREO)) { /* Vote PMAPP_SMPS_MODE_VOTE_PFM for headset */ smps_mode = PMAPP_SMPS_MODE_VOTE_PFM; MM_DBG("snddev_icodec_open_rx: PMAPP_SMPS_MODE_VOTE_PFM \n"); } else MM_DBG("snddev_icodec_open_rx: PMAPP_SMPS_MODE_VOTE_PWM \n"); /* Vote for SMPS mode*/ err = pmapp_smps_mode_vote(SMPS_AUDIO_PLAYBACK_ID, PMAPP_VREG_S4, smps_mode); if (err != 0) MM_ERR("pmapp_smps_mode_vote error %d\n", err); /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ trc = clk_set_rate(drv->rx_mclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) goto error_invalid_freq; clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); /* clk_set_rate(drv->lpa_codec_clk, 1); */ /* Remove if use pcom */ clk_enable(drv->lpa_p_clk); clk_enable(drv->lpa_codec_clk); clk_enable(drv->lpa_core_clk); /* Enable LPA sub system */ drv->lpa = lpa_get(); if (!drv->lpa) goto error_lpa; lpa_config.sample_rate = icodec->sample_rate; lpa_config.sample_width = 16; lpa_config.output_interface = LPA_OUTPUT_INTF_WB_CODEC; lpa_config.num_channels = icodec->data->channel_mode; lpa_cmd_codec_config(drv->lpa, &lpa_config); /* Set audio interconnect reg to LPA */ audio_interct_codec(AUDIO_INTERCT_LPA); /* Set MI2S */ mi2s_set_codec_output_path((icodec->data->channel_mode == 2 ? MI2S_CHAN_STEREO : MI2S_CHAN_MONO_PACKED), WT_16_BIT); if (icodec->data->voltage_on) icodec->data->voltage_on(); /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) goto error_adie; /* OSR default to 256, can be changed for power optimization * If OSR is to be changed, need clock API for setting the divider */ adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); lpa_cmd_enable_codec(drv->lpa, 1); /* Start AFE */ afe_config.sample_rate = icodec->sample_rate / 1000; afe_config.channel_mode = icodec->data->channel_mode; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_RX, &afe_config); if (IS_ERR_VALUE(trc)) goto error_afe; /* Enable ADIE */ adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Enable power amplifier */ if (icodec->data->pamp_on) icodec->data->pamp_on(); icodec->enabled = 1; wake_unlock(&drv->rx_idlelock); return 0; error_afe: adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; error_adie: lpa_put(drv->lpa); error_lpa: clk_disable(drv->lpa_p_clk); clk_disable(drv->lpa_codec_clk); clk_disable(drv->lpa_core_clk); clk_disable(drv->rx_sclk); clk_disable(drv->rx_mclk); error_invalid_freq: MM_ERR("encounter error\n"); wake_unlock(&drv->rx_idlelock); return -ENODEV; }
static __devinit int sec_battery_probe(struct platform_device *pdev) { struct sec_battery_platform_data *pdata = pdev->dev.platform_data; struct chg_data *chg; int ret = 0; pr_info("%s : Samsung Battery Driver Loading\n", __func__); chg = kzalloc(sizeof(*chg), GFP_KERNEL); if (!chg) return -ENOMEM; chg->pdata = pdata; if (!chg->pdata || !chg->pdata->adc_table) { pr_err("%s : No platform data & adc_table supplied\n", __func__); ret = -EINVAL; goto err_bat_table; } chg->psy_bat.name = "battery", chg->psy_bat.type = POWER_SUPPLY_TYPE_BATTERY, chg->psy_bat.properties = sec_battery_props, chg->psy_bat.num_properties = ARRAY_SIZE(sec_battery_props), chg->psy_bat.get_property = sec_bat_get_property, chg->psy_usb.name = "usb", chg->psy_usb.type = POWER_SUPPLY_TYPE_USB, chg->psy_usb.supplied_to = supply_list, chg->psy_usb.num_supplicants = ARRAY_SIZE(supply_list), chg->psy_usb.properties = sec_power_properties, chg->psy_usb.num_properties = ARRAY_SIZE(sec_power_properties), chg->psy_usb.get_property = sec_usb_get_property, chg->psy_ac.name = "ac", chg->psy_ac.type = POWER_SUPPLY_TYPE_MAINS, chg->psy_ac.supplied_to = supply_list, chg->psy_ac.num_supplicants = ARRAY_SIZE(supply_list), chg->psy_ac.properties = sec_power_properties, chg->psy_ac.num_properties = ARRAY_SIZE(sec_power_properties), chg->psy_ac.get_property = sec_ac_get_property, chg->present = 1; chg->polling_interval = POLLING_INTERVAL; chg->bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD; chg->bat_info.batt_is_full = false; chg->set_charge_timeout = false; chg->bat_info.batt_improper_ta = false; chg->is_recharging = false; #ifdef CONFIG_BATTERY_MAX17042 // Get battery type from fuelgauge driver. if(chg->pdata && chg->pdata->fuelgauge_cb) chg->battery_type = (battery_type_t)chg->pdata->fuelgauge_cb( REQ_TEST_MODE_INTERFACE, TEST_MODE_BATTERY_TYPE_CHECK, 0); // Check UV charging case. if(chg->pdata && chg->pdata->pmic_charger && chg->pdata->pmic_charger->get_connection_status) { if(chg->pdata->pmic_charger->get_connection_status() && check_UV_charging_case(chg)) chg->low_batt_boot_flag = true; } else chg->low_batt_boot_flag = false; // init delayed work INIT_DELAYED_WORK(&chg->full_chg_work, full_comp_work_handler); // Init low batt check threshold values. if(chg->battery_type == SDI_BATTERY_TYPE) chg->check_start_vol = 3550; // Under 3.55V else if(chg->battery_type == ATL_BATTERY_TYPE) chg->check_start_vol = 3450; // Under 3.45V #endif chg->cable_status = CABLE_TYPE_NONE; chg->charging_status = CHARGING_STATUS_NONE; mutex_init(&chg->mutex); platform_set_drvdata(pdev, chg); wake_lock_init(&chg->vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present"); wake_lock_init(&chg->work_wake_lock, WAKE_LOCK_SUSPEND, "sec_battery_work"); INIT_WORK(&chg->bat_work, sec_bat_work); chg->monitor_wqueue = create_freezeable_workqueue(dev_name(&pdev->dev)); if (!chg->monitor_wqueue) { pr_err("Failed to create freezeable workqueue\n"); ret = -ENOMEM; goto err_wake_lock; } chg->last_poll = alarm_get_elapsed_realtime(); alarm_init(&chg->alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, sec_battery_alarm); /* init power supplier framework */ ret = power_supply_register(&pdev->dev, &chg->psy_bat); if (ret) { pr_err("Failed to register power supply psy_bat\n"); goto err_wqueue; } ret = power_supply_register(&pdev->dev, &chg->psy_usb); if (ret) { pr_err("Failed to register power supply psy_usb\n"); goto err_supply_unreg_bat; } ret = power_supply_register(&pdev->dev, &chg->psy_ac); if (ret) { pr_err("Failed to register power supply psy_ac\n"); goto err_supply_unreg_usb; } sec_bat_create_attrs(chg->psy_bat.dev); chg->callbacks.set_cable = sec_bat_set_cable; chg->callbacks.set_status = sec_bat_set_status; chg->callbacks.force_update = sec_bat_force_update; if (chg->pdata->register_callbacks) chg->pdata->register_callbacks(&chg->callbacks); wake_lock(&chg->work_wake_lock); queue_work(chg->monitor_wqueue, &chg->bat_work); p1_lpm_mode_check(chg); return 0; err_supply_unreg_ac: power_supply_unregister(&chg->psy_ac); err_supply_unreg_usb: power_supply_unregister(&chg->psy_usb); err_supply_unreg_bat: power_supply_unregister(&chg->psy_bat); err_wqueue: destroy_workqueue(chg->monitor_wqueue); cancel_work_sync(&chg->bat_work); alarm_cancel(&chg->alarm); err_wake_lock: wake_lock_destroy(&chg->work_wake_lock); wake_lock_destroy(&chg->vbus_wake_lock); mutex_destroy(&chg->mutex); err_bat_table: kfree(chg); return ret; }
static int sec_cable_status_update(struct chg_data *chg) { int ret; bool vdc_status = false; ktime_t ktime; struct timespec cur_time; /* if max8998 has detected vdcin */ if (chg->pdata && chg->pdata->pmic_charger && chg->pdata->pmic_charger->get_connection_status && chg->pdata->pmic_charger->get_connection_status()) { vdc_status = true; if (chg->bat_info.dis_reason) { pr_info("%s : battery status discharging : %d\n", __func__, chg->bat_info.dis_reason); /* have vdcin, but cannot charge */ chg->charging = false; ret = sec_bat_charging_control(chg); if (ret < 0) goto err; chg->bat_info.charging_status = chg->bat_info.batt_is_full ? POWER_SUPPLY_STATUS_FULL : POWER_SUPPLY_STATUS_NOT_CHARGING; chg->discharging_time = 0; chg->set_batt_full = 0; goto update; } else if (chg->discharging_time == 0) { ktime = alarm_get_elapsed_realtime(); cur_time = ktime_to_timespec(ktime); chg->discharging_time = chg->bat_info.batt_is_full || chg->set_charge_timeout ? cur_time.tv_sec + TOTAL_RECHARGING_TIME : cur_time.tv_sec + TOTAL_CHARGING_TIME; } /* able to charge */ chg->charging = true; /* if we have vdcin but we cannot detect the cable type, force to AC so we can charge anyway */ if (chg->cable_status == CABLE_TYPE_NONE) chg->cable_status = CABLE_TYPE_AC; ret = sec_bat_charging_control(chg); if (ret < 0) goto err; chg->bat_info.charging_status = chg->bat_info.batt_is_full ? POWER_SUPPLY_STATUS_FULL : POWER_SUPPLY_STATUS_CHARGING; } else { /* no vdc in, not able to charge */ vdc_status = false; chg->charging = false; ret = sec_bat_charging_control(chg); if (ret < 0) goto err; chg->bat_info.charging_status = POWER_SUPPLY_STATUS_DISCHARGING; chg->bat_info.batt_is_full = false; chg->set_charge_timeout = false; chg->set_batt_full = 0; chg->bat_info.dis_reason = 0; chg->discharging_time = 0; chg->bat_info.batt_improper_ta = false; chg->is_recharging = false; } update: if(chg->bat_info.charging_status == POWER_SUPPLY_STATUS_FULL || chg->bat_info.charging_status == POWER_SUPPLY_STATUS_CHARGING) { /* Update DISCHARGING status in case of USB cable or Improper charger */ if(chg->cable_status==CABLE_TYPE_USB || chg->bat_info.batt_improper_ta) chg->bat_info.charging_status = POWER_SUPPLY_STATUS_DISCHARGING; } if ((chg->cable_status != CABLE_TYPE_NONE) && vdc_status) wake_lock(&chg->vbus_wake_lock); else wake_lock_timeout(&chg->vbus_wake_lock, HZ / 2); return 0; err: return ret; }
static void pcm_in_prevent_sleep(struct pcm *audio) { pr_debug("%s:\n", __func__); wake_lock(&audio->wakelock); wake_lock(&audio->idlelock); }
static int __devinit hs_probe(struct platform_device *pdev) { int rc = 0; struct input_dev *ipdev; printk(" hs_probe start. \n"); //ps2 p13106 hs = kzalloc(sizeof(struct msm_handset), GFP_KERNEL); if (!hs) return -ENOMEM; hs->sdev.name = "h2w"; hs->sdev.print_name = msm_headset_print_name; rc = switch_dev_register(&hs->sdev); if (rc) goto err_switch_dev_register; ipdev = input_allocate_device(); if (!ipdev) { rc = -ENOMEM; goto err_alloc_input_dev; } input_set_drvdata(ipdev, hs); hs->ipdev = ipdev; if (pdev->dev.platform_data) hs->hs_pdata = pdev->dev.platform_data; if (hs->hs_pdata->hs_name) ipdev->name = hs->hs_pdata->hs_name; else ipdev->name = DRIVER_NAME; //////////////////////////////////////////////////////////////////////////////////// #if defined(T_LASER2) printk(" CONFIG_MACH_MSM8X55_LASER2 hs_probe start. \n"); //ps2 p13106 hs->type=EARJACK_STATE_OFF; hs->hs_on=hs->mic_on=0; hs->remotekey_pressed = 0; hs->remotekey_first = 0; hs->remotekey_count=0; #if (BOARD_VER > WS20 ) // Initialize Voltage Mic bias vreg_Earjack_GP6 = vreg_get(NULL, "gp6"); rc = vreg_set_level(vreg_Earjack_GP6, 2700); if (rc) { printk(KERN_ERR "%s: vreg_Earjack_GP6 set level failed (%d)\n", __func__, rc); return -1; } rc = vreg_disable(vreg_Earjack_GP6); if (rc) { printk(KERN_ERR "%s: #include <mach/vreg.h> enable failed (%d)\n", __func__, rc); return -1; } #endif //(BOARD_VER > WS20 ) // Initialize Work Queue INIT_DELAYED_WORK(&earjack_work,earjack_detect_func); // INIT WORK INIT_DELAYED_WORK(&remotekey_work,remotekey_detect_func); // Initialize Wakelocks wake_lock_init(&earjack_wake_lock, WAKE_LOCK_SUSPEND, "earjack_wake_lock_init"); wake_lock_init(&remotekey_wake_lock, WAKE_LOCK_SUSPEND, "remotekey_wake_lock_init"); // Get GPIO's gpio_request(EARJACK_DET, "earjack_det"); gpio_request(REMOTEKEY_DET, "remotekey_det"); gpio_tlmm_config(GPIO_CFG(EARJACK_DET, 0, GPIO_CFG_INPUT,GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE); rc = request_irq(gpio_to_irq(EARJACK_DET), Earjack_Det_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "earjack_det-irq", hs); gpio_tlmm_config(GPIO_CFG(REMOTEKEY_DET, 0, GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); rc = request_irq(gpio_to_irq(REMOTEKEY_DET), Remotekey_Det_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "remotekey-irq", hs); // Init Mutex set_irq_wake(gpio_to_irq(EARJACK_DET), 1); set_irq_wake(gpio_to_irq(REMOTEKEY_DET), 1); // check earjack is inserted wake_lock(&earjack_wake_lock); schedule_delayed_work(&earjack_work, 10); // after 100ms start function of earjack_detect_func #endif // defined(T_LASER2) ipdev->id.vendor = 0x0001; ipdev->id.product = 1; ipdev->id.version = 1; input_set_capability(ipdev, EV_KEY, KEY_MEDIA); input_set_capability(ipdev, EV_KEY, KEY_VOLUMEUP); input_set_capability(ipdev, EV_KEY, KEY_VOLUMEDOWN); input_set_capability(ipdev, EV_SW, SW_HEADPHONE_INSERT); input_set_capability(ipdev, EV_SW, SW_MICROPHONE_INSERT); input_set_capability(ipdev, EV_KEY, KEY_POWER); input_set_capability(ipdev, EV_KEY, KEY_END); rc = input_register_device(ipdev); if (rc) { dev_err(&ipdev->dev, "hs_probe: input_register_device rc=%d\n", rc); goto err_reg_input_dev; } platform_set_drvdata(pdev, hs); rc = hs_rpc_init(); if (rc) { dev_err(&ipdev->dev, "rpc init failure\n"); goto err_hs_rpc_init; } return 0; err_hs_rpc_init: input_unregister_device(ipdev); ipdev = NULL; err_reg_input_dev: input_free_device(ipdev); err_alloc_input_dev: switch_dev_unregister(&hs->sdev); err_switch_dev_register: kfree(hs); return rc; }
static irqreturn_t gpio_event_input_irq_handler(int irq, void *dev_id) { struct gpio_key_state *ks = dev_id; struct gpio_input_state *ds = ks->ds; int keymap_index = ks - ds->key_state; const struct gpio_event_direct_entry *key_entry; unsigned long irqflags; #ifndef CONFIG_MFD_MAX8957 int pressed; #endif KEY_LOGD("%s, irq=%d, use_irq=%d\n", __func__, irq, ds->use_irq); if (!ds->use_irq) return IRQ_HANDLED; key_entry = &ds->info->keymap[keymap_index]; if (key_entry->code == KEY_POWER && power_key_intr_flag == 0) { irq_set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING); power_key_intr_flag = 1; KEY_LOGD("%s, keycode = %d, first intr", __func__, key_entry->code); } if (ds->info->debounce_time.tv64) { spin_lock_irqsave(&ds->irq_lock, irqflags); if (ks->debounce & DEBOUNCE_WAIT_IRQ) { ks->debounce = DEBOUNCE_UNKNOWN; if (ds->debounce_count++ == 0) { wake_lock(&ds->wake_lock); #ifndef CONFIG_MFD_MAX8957 hrtimer_start( &ds->timer, ds->info->debounce_time, HRTIMER_MODE_REL); #endif } if (ds->info->flags & GPIOEDF_PRINT_KEY_DEBOUNCE) KEY_LOGD("gpio_event_input_irq_handler: " "key %x-%x, %d (%d) start debounce\n", ds->info->type, key_entry->code, keymap_index, key_entry->gpio); } else { disable_irq_nosync(irq); ks->debounce = DEBOUNCE_UNSTABLE; } spin_unlock_irqrestore(&ds->irq_lock, irqflags); } else { #ifdef CONFIG_MFD_MAX8957 queue_work(ki_queue, &ks->work); #else pressed = gpio_get_value(key_entry->gpio) ^ !(ds->info->flags & GPIOEDF_ACTIVE_HIGH); if (ds->info->flags & GPIOEDF_PRINT_KEYS) KEY_LOGD("gpio_event_input_irq_handler: key %x-%x, %d " "(%d) changed to %d\n", ds->info->type, key_entry->code, keymap_index, key_entry->gpio, pressed); input_event(ds->input_devs->dev[key_entry->dev], ds->info->type, key_entry->code, pressed); input_sync(ds->input_devs->dev[key_entry->dev]); #endif } return IRQ_HANDLED; }
void esp_wake_lock(void) { #ifdef CONFIG_HAS_WAKELOCK wake_lock(&esp_wake_lock_); #endif }
static int __init msm_otg_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; struct msm_otg *dev; struct msm_otg_platform_data *pdata; dev = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); if (!dev) return -ENOMEM; dev->otg.dev = &pdev->dev; if (pdev->dev.platform_data) { pdata = pdev->dev.platform_data; dev->rpc_connect = pdata->rpc_connect; dev->phy_reset = pdata->phy_reset; } if (dev->rpc_connect) { ret = dev->rpc_connect(1); pr_info("%s: rpc_connect(%d)\n", __func__, ret); if (ret) { pr_err("%s: rpc connect failed\n", __func__); ret = -ENODEV; goto free_dev; } } dev->clk = clk_get(&pdev->dev, "usb_hs_clk"); if (IS_ERR(dev->clk)) { pr_err("%s: failed to get usb_hs_clk\n", __func__); ret = PTR_ERR(dev->clk); goto rpc_fail; } dev->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); if (IS_ERR(dev->clk)) { pr_err("%s: failed to get usb_hs_pclk\n", __func__); ret = PTR_ERR(dev->pclk); goto put_clk; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { pr_err("%s: failed to get platform resource mem\n", __func__); ret = -ENODEV; goto put_pclk; } dev->regs = ioremap(res->start, resource_size(res)); if (!dev->regs) { pr_err("%s: ioremap failed\n", __func__); ret = -ENOMEM; goto put_pclk; } dev->irq = platform_get_irq(pdev, 0); if (!dev->irq) { pr_err("%s: platform_get_irq failed\n", __func__); ret = -ENODEV; goto free_regs; } /* enable clocks */ clk_enable(dev->clk); clk_enable(dev->pclk); otg_reset(dev); ret = request_irq(dev->irq, msm_otg_irq, IRQF_SHARED, "msm_otg", dev); if (ret) { pr_info("%s: request irq failed\n", __func__); clk_disable(dev->clk); clk_disable(dev->pclk); goto free_regs; } the_msm_otg = dev; dev->otg.set_peripheral = msm_otg_set_peripheral; dev->otg.set_host = msm_otg_set_host; dev->otg.set_suspend = msm_otg_set_suspend; if (otg_set_transceiver(&dev->otg)) { WARN_ON(1); goto free_regs; } wake_lock_init(&dev->wlock, WAKE_LOCK_SUSPEND, "usb_bus_active"); wake_lock(&dev->wlock); msm_otg_debugfs_init(dev); device_init_wakeup(&pdev->dev, 1); return 0; free_regs: iounmap(dev->regs); put_pclk: clk_put(dev->pclk); put_clk: clk_put(dev->clk); rpc_fail: dev->rpc_connect(0); free_dev: kfree(dev); return ret; }
static inline void prevent_suspend(void) { wake_lock(&s5k3e2fx_wake_lock); }
void wcnss_prevent_suspend() { if (penv) wake_lock(&penv->wcnss_wake_lock); }
static int if_usb_resume(struct usb_interface *intf) { int i, ret; struct sk_buff *skb; struct usb_link_device *usb_ld = usb_get_intfdata(intf); struct if_usb_devdata *pipe; struct urb *urb; spin_lock_irq(&usb_ld->lock); if (!atomic_dec_return(&usb_ld->suspend_count)) { spin_unlock_irq(&usb_ld->lock); mif_debug("\n"); wake_lock(&usb_ld->susplock); /* HACK: Runtime pm does not allow requesting autosuspend from * resume callback, delayed it after resume */ queue_delayed_work(system_nrt_wq, &usb_ld->runtime_pm_work, msecs_to_jiffies(50)); for (i = 0; i < IF_USB_DEVNUM_MAX; i++) { pipe = &usb_ld->devdata[i]; while ((urb = usb_get_from_anchor(&pipe->urbs))) { ret = usb_rx_submit(pipe, urb, GFP_KERNEL); if (ret < 0) { usb_put_urb(urb); mif_err( "usb_rx_submit error with (%d)\n", ret); return ret; } usb_put_urb(urb); } } while ((urb = usb_get_from_anchor(&usb_ld->deferred))) { mif_debug("got urb (0x%p) from anchor & resubmit\n", urb); ret = usb_submit_urb(urb, GFP_KERNEL); if (ret < 0) { mif_err("resubmit failed\n"); skb = urb->context; dev_kfree_skb_any(skb); usb_free_urb(urb); ret = pm_runtime_put_autosuspend( &usb_ld->usbdev->dev); if (ret < 0 && ret != -EAGAIN) mif_debug("pm_runtime_put_autosuspend " "failed: %d\n", ret); } } SET_SLAVE_WAKEUP(usb_ld->pdata, 1); udelay(100); SET_SLAVE_WAKEUP(usb_ld->pdata, 0); /* if_usb_resume() is atomic. post_resume_work is * a kind of bottom halves */ queue_delayed_work(system_nrt_wq, &usb_ld->post_resume_work, 0); return 0; } spin_unlock_irq(&usb_ld->lock); return 0; }
void ssp_dump_task(struct work_struct *work) { #if CONFIG_SEC_DEBUG struct ssp_big *big; struct file *dump_file; struct ssp_msg *msg; char *buffer; char strFilePath[100]; struct timeval cur_time; mm_segment_t fs; int buf_len, packet_len, residue; int iRet = 0, index = 0, iRetTrans = 0, iRetWrite = 0; big = container_of(work, struct ssp_big, work); ssp_errf("start ssp dumping (%d)(%d)", big->data->bMcuDumpMode, big->data->uDumpCnt); big->data->uDumpCnt++; wake_lock(&big->data->ssp_wake_lock); fs = get_fs(); set_fs(get_ds()); if (big->data->bMcuDumpMode == true) { do_gettimeofday(&cur_time); #ifdef CONFIG_SENSORS_SSP_ENG snprintf(strFilePath, sizeof(strFilePath), "%s%d.dump", DUMP_FILE_PATH, (int)cur_time.tv_sec); dump_file = filp_open(strFilePath, O_RDWR | O_CREAT | O_APPEND, 0660); #else snprintf(strFilePath, sizeof(strFilePath), "%s.dump", DUMP_FILE_PATH); dump_file = filp_open(strFilePath, O_RDWR | O_CREAT | O_TRUNC, 0660); #endif if (IS_ERR(dump_file)) { ssp_errf("Can't open dump file"); set_fs(fs); iRet = PTR_ERR(dump_file); wake_unlock(&big->data->ssp_wake_lock); kfree(big); return; } } else { dump_file = NULL; } buf_len = big->length > DATA_PACKET_SIZE ? DATA_PACKET_SIZE : big->length; buffer = kzalloc(buf_len, GFP_KERNEL); residue = big->length; while (residue > 0) { packet_len = residue > DATA_PACKET_SIZE ? DATA_PACKET_SIZE : residue; msg = kzalloc(sizeof(*msg), GFP_KERNEL); msg->cmd = MSG2SSP_AP_GET_BIG_DATA; msg->length = packet_len; msg->options = AP2HUB_READ | (index++ << SSP_INDEX); msg->data = big->addr; msg->buffer = buffer; msg->free_buffer = 0; iRetTrans = ssp_spi_sync(big->data, msg, 1000); if (iRetTrans != SUCCESS) { ssp_errf("Fail to receive data %d (%d)", iRetTrans, residue); break; } if (big->data->bMcuDumpMode == true) { iRetWrite = vfs_write(dump_file, (char __user *)buffer, packet_len, &dump_file->f_pos); if (iRetWrite < 0) { ssp_errf("Can't write dump to file"); break; } } residue -= packet_len; } if (big->data->bMcuDumpMode == true) { if (iRetTrans != SUCCESS || iRetWrite < 0) { /* error case */ char FAILSTRING[100]; snprintf(FAILSTRING, sizeof(FAILSTRING), "FAIL OCCURED(%d)(%d)(%d)", iRetTrans, iRetWrite, big->length); vfs_write(dump_file, (char __user *)FAILSTRING, strlen(FAILSTRING), &dump_file->f_pos); } filp_close(dump_file, current->files); } big->data->bDumping = false; set_fs(fs); wake_unlock(&big->data->ssp_wake_lock); kfree(buffer); kfree(big); #endif ssp_errf("done"); }
static int msm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { DECLARE_COMPLETION_ONSTACK(complete); struct msm_i2c_dev *dev = i2c_get_adapdata(adap); int ret, ret_wait; long timeout; unsigned long flags; /* * If there is an i2c_xfer after driver has been suspended, * grab wakelock to abort suspend. */ if (dev->is_suspended) wake_lock(&dev->wakelock); clk_enable(dev->clk); enable_irq(dev->irq); ret = msm_i2c_poll_notbusy(dev, 1, msgs); if (ret) { dev_err(dev->dev, "Still busy in starting xfer(%02X)\n", msgs->addr); if (!dev->skip_recover) { ret = msm_i2c_recover_bus_busy(dev); if (ret) goto err; } } spin_lock_irqsave(&dev->lock, flags); if (dev->flush_cnt) { dev_warn(dev->dev, "%d unrequested bytes read\n", dev->flush_cnt); } dev->msg = msgs; dev->rem = num; dev->pos = -1; dev->ret = num; dev->need_flush = false; dev->flush_cnt = 0; dev->cnt = msgs->len; dev->complete = &complete; msm_i2c_interrupt_locked(dev); spin_unlock_irqrestore(&dev->lock, flags); /* * Now that we've setup the xfer, the ISR will transfer the data * and wake us up with dev->err set if there was an error */ timeout = wait_for_completion_timeout(&complete, HZ); ret_wait = msm_i2c_poll_notbusy(dev, 0, msgs); spin_lock_irqsave(&dev->lock, flags); if (dev->flush_cnt) { dev_warn(dev->dev, "%d unrequested bytes read\n", dev->flush_cnt); } ret = dev->ret; dev->complete = NULL; dev->msg = NULL; dev->rem = 0; dev->pos = 0; dev->ret = 0; dev->flush_cnt = 0; dev->cnt = 0; spin_unlock_irqrestore(&dev->lock, flags); if (ret_wait) /* Read may not have stopped in time */ { dev_err(dev->dev, "Still busy after xfer completion (%02X)\n", msgs->addr); if (ret_wait == -GSENSOR_TIMEDOUT) ret = 2; // in most situations the value of ret is 2 (dev->ret), we set it to 2 just to be sure that function i2c_read_block doesn't repeats the read if (!dev->skip_recover) { ret_wait = msm_i2c_recover_bus_busy(dev); if (ret_wait) goto err; } } if (!timeout) { dev_err(dev->dev, "Transaction timed out\n"); ret = -ETIMEDOUT; } if (ret < 0) { dev_err(dev->dev, "Error during data xfer (%d) (%02X)\n", ret, msgs->addr); if (!dev->skip_recover) msm_i2c_recover_bus_busy(dev); } err: disable_irq(dev->irq); clk_disable(dev->clk); if (dev->is_suspended) wake_unlock(&dev->wakelock); return ret; }
int debug_crash_dump(struct ssp_data *data, char *pchRcvDataFrame, int iLength) { struct timeval cur_time; char strFilePath[100]; int iRetWrite = 0; unsigned char datacount = pchRcvDataFrame[1]; unsigned int databodysize = iLength - 2; char *databody = &pchRcvDataFrame[2]; /* if(iLength != DEBUG_DUMP_DATA_SIZE) { ssp_errf("data length error(%d)", iLength); return FAIL; } else ssp_errf("length(%d)", databodysize); */ ssp_errf("length(%d)", databodysize); if (data->bSspShutdown) { ssp_infof("ssp shutdown, stop dumping"); return FAIL; } if (data->bMcuDumpMode == true) { wake_lock(&data->ssp_wake_lock); if (data->realtime_dump_file == NULL) { backup_fs = get_fs(); set_fs(get_ds()); do_gettimeofday(&cur_time); snprintf(strFilePath, sizeof(strFilePath), "%s%d.dump", DEBUG_DUMP_FILE_PATH, (int)cur_time.tv_sec); data->realtime_dump_file = filp_open(strFilePath, O_RDWR | O_CREAT | O_APPEND, 0660); ssp_err("save_crash_dump : open file(%s)", strFilePath); if (IS_ERR(data->realtime_dump_file)) { ssp_errf("Can't open dump file"); set_fs(backup_fs); data->realtime_dump_file = NULL; wake_unlock(&data->ssp_wake_lock); return FAIL; } } data->total_dump_size += databodysize; /* ssp_errf("total receive size(%d)", data->total_dump_size); */ iRetWrite = vfs_write(data->realtime_dump_file, (char __user *)databody, databodysize, &data->realtime_dump_file->f_pos); if (iRetWrite < 0) { ssp_errf("Can't write dump to file"); wake_unlock(&data->ssp_wake_lock); return FAIL; } if (datacount == DEBUG_DUMP_DATA_COMPLETE) { ssp_errf("close file(size=%d)", data->total_dump_size); filp_close(data->realtime_dump_file, current->files); set_fs(backup_fs); data->uDumpCnt++; data->total_dump_size = 0; data->realtime_dump_file = NULL; data->bDumping = false; } wake_unlock(&data->ssp_wake_lock); /* if(iLength == 2*1024) queue_refresh_task(data, 0); */ } return SUCCESS; }
static int snddev_icodec_open_tx(struct snddev_icodec_state *icodec) { int trc; int i, err; struct msm_afe_config afe_config; struct snddev_icodec_drv_state *drv = &snddev_icodec_drv;; wake_lock(&drv->tx_idlelock); /* Vote for PWM mode*/ err = pmapp_smps_mode_vote(SMPS_AUDIO_RECORD_ID, PMAPP_VREG_S4, PMAPP_SMPS_MODE_VOTE_PWM); if (err != 0) MM_ERR("pmapp_smps_mode_vote error %d\n", err); /* Reuse pamp_on for TX platform-specific setup */ if (icodec->data->pamp_on) icodec->data->pamp_on(); for (i = 0; i < icodec->data->pmctl_id_sz; i++) { pmic_hsed_enable(icodec->data->pmctl_id[i], PM_HSED_ENABLE_PWM_TCXO); } /* enable MI2S TX master block */ /* enable MI2S TX bit clock */ trc = clk_set_rate(drv->tx_mclk, SNDDEV_ICODEC_CLK_RATE(icodec->sample_rate)); if (IS_ERR_VALUE(trc)) goto error_invalid_freq; clk_enable(drv->tx_mclk); clk_enable(drv->tx_sclk); /* Set MI2S */ mi2s_set_codec_input_path((icodec->data->channel_mode == 2 ? MI2S_CHAN_STEREO : MI2S_CHAN_MONO_RAW), WT_16_BIT); /* Configure ADIE */ trc = adie_codec_open(icodec->data->profile, &icodec->adie_path); if (IS_ERR_VALUE(trc)) goto error_adie; /* Enable ADIE */ adie_codec_setpath(icodec->adie_path, icodec->sample_rate, 256); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_READY); adie_codec_proceed_stage(icodec->adie_path, ADIE_CODEC_DIGITAL_ANALOG_READY); /* Start AFE */ afe_config.sample_rate = icodec->sample_rate / 1000; afe_config.channel_mode = icodec->data->channel_mode; afe_config.volume = AFE_VOLUME_UNITY; trc = afe_enable(AFE_HW_PATH_CODEC_TX, &afe_config); if (IS_ERR_VALUE(trc)) goto error_afe; icodec->enabled = 1; wake_unlock(&drv->tx_idlelock); return 0; error_afe: adie_codec_close(icodec->adie_path); icodec->adie_path = NULL; error_adie: clk_disable(drv->tx_sclk); clk_disable(drv->tx_mclk); error_invalid_freq: /* Disable mic bias */ for (i = 0; i < icodec->data->pmctl_id_sz; i++) { pmic_hsed_enable(icodec->data->pmctl_id[i], PM_HSED_ENABLE_OFF); } if (icodec->data->pamp_off) icodec->data->pamp_off(); MM_ERR("encounter error\n"); wake_unlock(&drv->tx_idlelock); return -ENODEV; }
static long ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { #ifdef QA_TEST int i; #endif /* DbgOut(KERN_INFO "tspdrv: ioctl cmd[0x%x].\n", cmd); */ switch (cmd) { case TSPDRV_STOP_KERNEL_TIMER: /* ** As we send one sample ahead of time, we need to finish ** playing the last sample before stopping the timer. ** So we just set a flag here. */ if (true == g_bisplaying) g_bstoprequested = true; #ifdef VIBEOSKERNELPROCESSDATA /* Last data processing to disable amp and stop timer */ VibeOSKernelProcessData(NULL); #endif #ifdef QA_TEST if (g_nforcelog_index) { for (i = 0; i < g_nforcelog_index; i++) { printk(KERN_INFO "%d\t%d\n" , g_ntime, g_nforcelog[i]); g_ntime += TIME_INCREMENT; } } g_ntime = 0; g_nforcelog_index = 0; #endif break; case TSPDRV_MAGIC_NUMBER: case TSPDRV_SET_MAGIC_NUMBER: filp->private_data = (void *)TSPDRV_MAGIC_NUMBER; break; case TSPDRV_ENABLE_AMP: wake_lock(&vib_wake_lock); ImmVibeSPI_ForceOut_AmpEnable(arg); DbgRecorderReset((arg)); DbgRecord((arg, ";------- TSPDRV_ENABLE_AMP ---------\n")); break; case TSPDRV_DISABLE_AMP: /* ** Small fix for now to handle proper combination of ** TSPDRV_STOP_KERNEL_TIMER and TSPDRV_DISABLE_AMP together ** If a stop was requested, ignore the request as the amp ** will be disabled by the timer proc when it's ready */ if (!g_bstoprequested) ImmVibeSPI_ForceOut_AmpDisable(arg); wake_unlock(&vib_wake_lock); break; case TSPDRV_GET_NUM_ACTUATORS: return NUM_ACTUATORS; } return 0; }
/****************************************************************************** * function: smt113j_spi_thread_Init * brief : * date : * author : * * return : none * input : none * output : none ******************************************************************************/ static int smt113j_spi_thread_Init ( void ) { int ret = 0; struct sched_param param = { .sched_priority = 99 }; DEBUG_PRINT("smt113j_spi_thread_Init: Start"); spi_work_thread = kmalloc ( sizeof ( smt113j_spi_thread_t ), GFP_KERNEL ); if ( !spi_work_thread ) { ERROR_PRINT ("smt113j_spi_thread_Init : Kmalloc Error"); return ( -EFAULT ); } spi_work_thread->status = SMT113J_SPI_SYNC_STOP; spin_lock_init( &spi_work_thread->tmm_lock ); init_waitqueue_head ( &spi_work_thread->thread_wait ); /*** Thread generation and run ***/ spi_work_thread->thread_task = kthread_run ( smt113j_spi_thread_loop, NULL, "SMT113J_SPI_Task" ); if ( IS_ERR ( spi_work_thread->thread_task )) { ERROR_PRINT ("smt113j_spi_thread_Init : kthread_run error : %p", spi_work_thread->thread_task); goto ERROR2; } ret = sched_setscheduler ( spi_work_thread->thread_task, SCHED_FIFO, ¶m ); if ( ret < 0 ) { ERROR_PRINT ( "smt113j_spi_thread_Init : sched_setscheduler error ret[ %d ]", ret ); goto ERROR3; } DEBUG_PRINT("smt113j_spi_thread_Init: End"); return ( ret ); ERROR3: spi_work_thread->status = SMT113J_SPI_SYNC_STOP; wake_up_interruptible ( &( spi_work_thread->thread_wait )); kthread_stop ( spi_work_thread->thread_task ); ERROR2: kfree ( spi_work_thread ); ERROR_PRINT ("smt113j_spi_thread_Init : Error"); return ( ret ); } /****************************************************************************** * function: smt113j_spi_thread_Start * brief : * date : * author : * * return : none * input : none * output : none ******************************************************************************/ static int smt113j_spi_thread_Start ( void ) { DEBUG_PRINT("smt113j_spi_thread_Start : Start!"); DEBUG_PRINT("-> spi_work_thread->status[%d]", spi_work_thread->status ); /* multiple check */ if ( SMT113J_SPI_SYNC_RUN == spi_work_thread->status ) { DEBUG_PRINT("smt113j_spi_thread_Start( Double ) : End!"); return ( 0 ); } /* thread run status set */ spi_work_thread->status = SMT113J_SPI_SYNC_RUN; pwrite = 0; pread = 0; wake_lock(&smt113j_spi_wake_lock); /* wakeup event */ wake_up_interruptible ( &(spi_work_thread->thread_wait )); DEBUG_PRINT("smt113j_spi_thread_Start : End!"); DEBUG_PRINT("-> spi_work_thread->status[%d]", spi_work_thread->status ); return ( 0 ); }
void baseband_xmm_set_power_status(unsigned int status) { struct baseband_power_platform_data *data = baseband_power_driver_data; int value = 0; unsigned long flags; pr_debug("%s n(%d),o(%d)\n", __func__, status, baseband_xmm_powerstate ); if (baseband_xmm_powerstate == status) return; switch (status) { case BBXMM_PS_L0: if (modem_sleep_flag) { pr_debug("%s Resume from L3 without calling resume" "function\n", __func__); baseband_xmm_power_driver_handle_resume(data); } pr_debug("PM_ST : L0\n"); baseband_xmm_powerstate = status; if (!wake_lock_active(&wakelock)) wake_lock(&wakelock); value = gpio_get_value(data->modem.xmm.ipc_hsic_active); //pr_debug("GPIO [R]: before L0 Host_active = %d \n", value); if (!value) { gpio_set_value(data->modem.xmm.ipc_hsic_active, 1); pr_debug("GPIO [W]: L0 Host_active -> 1 \n"); } if (modem_power_on) { modem_power_on = false; baseband_modem_power_on(data); } pr_debug("gpio host active high->\n"); break; case BBXMM_PS_L2: pr_debug("PM_ST : L2\n"); baseband_xmm_powerstate = status; spin_lock_irqsave(&xmm_lock, flags); if (wakeup_pending) { spin_unlock_irqrestore(&xmm_lock, flags); baseband_xmm_power_L2_resume(); } else { spin_unlock_irqrestore(&xmm_lock, flags); if (wake_lock_active(&wakelock)) wake_unlock(&wakelock); modem_sleep_flag = true; } if (short_autosuspend && enable_short_autosuspend && &usbdev->dev) { pr_debug("autosuspend delay %d ms, disable short_autosuspend\n",DEFAULT_AUTOSUSPEND_DELAY); queue_work(workqueue_susp, &work_defaultsusp); short_autosuspend = false; } break; case BBXMM_PS_L3: if (baseband_xmm_powerstate == BBXMM_PS_L2TOL0) { if (!gpio_get_value(data->modem.xmm.ipc_ap_wake)) { spin_lock_irqsave(&xmm_lock, flags); wakeup_pending = true; spin_unlock_irqrestore(&xmm_lock, flags); pr_info("%s: L2 race condition-CP wakeup" " pending\n", __func__); } } pr_info("L3\n"); if (wake_lock_active(&wakelock)) { pr_debug("%s: releasing wakelock before L3\n", __func__); wake_unlock(&wakelock); } if (wakeup_pending == false) { gpio_set_value(data->modem.xmm.ipc_hsic_active, 0); pr_debug("gpio host active low->\n"); } break; case BBXMM_PS_L2TOL0: spin_lock_irqsave(&xmm_lock, flags); system_suspending = false; wakeup_pending = false; spin_unlock_irqrestore(&xmm_lock, flags); /* do this only from L2 state */ if (baseband_xmm_powerstate == BBXMM_PS_L2) { baseband_xmm_powerstate = status; pr_debug("BB XMM POWER STATE = %d\n", status); baseband_xmm_power_L2_resume(); } baseband_xmm_powerstate = status; break; default: baseband_xmm_powerstate = status; break; } pr_debug("BB XMM POWER STATE = %s(%d)\n", pwrstate_cmt[status], status); }
static void gpio_keys_report_event(struct gpio_button_data *bdata) { struct gpio_keys_button *button = bdata->button; struct input_dev *input = bdata->input; unsigned int type = button->type ?: EV_KEY; int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low; #ifdef CONFIG_MACH_GC1 struct gpio_keys_drvdata *ddata = input_get_drvdata(input); struct gpio_button_data *tmp_bdata; static bool overlapped; static unsigned int hotkey; unsigned int index_hotkey = 0; bool zoomkey = false; #ifdef CONFIG_FAST_BOOT /*Fake pwr off control*/ if (fake_shut_down || fake_pressed) { if (button->code == KEY_POWER) { if (!!state) { printk(KERN_DEBUG"[Keys] start fake check\n"); fake_pressed = true; if (!wake_lock_active(&fake_lock)) wake_lock(&fake_lock); mod_timer(&fake_timer, jiffies + msecs_to_jiffies(500)); } else { printk(KERN_DEBUG"[Keys] end fake checkPwr 0\n"); fake_pressed = false; if (wake_lock_active(&fake_lock)) wake_unlock(&fake_lock); } } bdata->wakeup = false; return ; } #endif if (system_rev < 6 && system_rev >= 2) { if (overlapped) { if (hotkey == button->code && !state) { bdata->key_state = !!state; bdata->wakeup = false; overlapped = false; #ifdef CONFIG_SAMSUNG_PRODUCT_SHIP printk(KERN_DEBUG"[KEYS] Ignored\n"); #else printk(KERN_DEBUG"[KEYS] Ignore %d %d\n", hotkey, state); #endif return; } } gpio_keys_check_zoom_exception(button->code, &zoomkey, &hotkey, &index_hotkey); } else if (system_rev >= 6) { /*exclusive check for zoom dial*/ unsigned int zoom_type = 0; unsigned int current_zoom_state = 0; bool pass_cur_event = false; if (is_zoom_key(button->code, &zoom_type)) { current_zoom_state = check_zoom_state(ddata); if (zoom_type == ZOOM_IN && current_zoom_state == ZOOM_OUT) pass_cur_event = true; else if (zoom_type == ZOOM_OUT && current_zoom_state == ZOOM_IN) pass_cur_event = true; if (pass_cur_event) { #if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP) printk(KERN_DEBUG "[keys] Pass zoom" "current %d, code %d\n", current_zoom_state, button->code); #endif return ; } } } #endif if (type == EV_ABS) { if (state) { input_event(input, type, button->code, button->value); input_sync(input); } } else { if (bdata->wakeup && !state) { input_event(input, type, button->code, !state); input_sync(input); if (button->code == KEY_POWER) printk(KERN_DEBUG"[keys] f PWR %d\n", !state); } bdata->key_state = !!state; bdata->wakeup = false; #ifdef CONFIG_MACH_GC1 if (system_rev < 6 && system_rev >= 2 && zoomkey && state) { tmp_bdata = &ddata->data[index_hotkey]; if (tmp_bdata->key_state) { #ifdef CONFIG_SAMSUNG_PRODUCT_SHIP printk(KERN_DEBUG"[KEYS] overlapped\n"); #else printk(KERN_DEBUG"[KEYS] overlapped. Forced release c %d h %d\n", tmp_bdata->button->code, hotkey); #endif input_event(input, type, hotkey, 0); input_sync(input); overlapped = true; } } if (system_rev >= 6) { /* forced release*/ if (button->code == KEY_CAMERA_ZOOMIN && !state) { tmp_bdata = &ddata->data[5]; if (tmp_bdata->key_state) { input_event(input, type, 0x221, !!state); input_sync(input); printk(KERN_DEBUG"[KEYS] forced 0x221 key release\n"); } } if (button->code == KEY_CAMERA_ZOOMOUT && !state) { tmp_bdata = &ddata->data[6]; if (tmp_bdata->key_state) { input_event(input, type, 0x222, !!state); input_sync(input); printk(KERN_DEBUG"[KEYS] forced 0x222 key release\n"); } } /*forced press*/ if (button->code == 0x221 && state) { tmp_bdata = &ddata->data[3]; if (!tmp_bdata->key_state) { input_event(input, type, KEY_CAMERA_ZOOMIN, !!state); input_sync(input); printk(KERN_DEBUG"[KEYS] forced 0x215 key press\n"); } } if (button->code == 0x222 && state) { tmp_bdata = &ddata->data[4]; if (!tmp_bdata->key_state) { input_event(input, type, KEY_CAMERA_ZOOMOUT, !!state); input_sync(input); printk(KERN_DEBUG"[KEYS] forced 0x216 key press\n"); } } } #endif input_event(input, type, button->code, !!state); input_sync(input); if (button->code == KEY_POWER) printk(KERN_DEBUG"[keys]PWR %d\n", !!state); } }
static void twl6030_determine_charge_state(struct twl6030_bci_device_info *di) { u8 stat1; int newstate = STATE_BATTERY; /* TODO: i2c error -> fault? */ twl_i2c_read_u8(TWL6030_MODULE_CHARGER, &stat1, CONTROLLER_STAT1); /* TODO: why is STAT1.0 (BAT_TEMP_OVRANGE) always set? */ /* printk("battery: determine_charge_state() stat1=%02x int1=%02x\n", stat1, int1); */ if (stat1 & VBUS_DET) { /* dedicated charger detected by PHY? */ if (di->usb_event == USB_EVENT_CHARGER) newstate = STATE_AC; else newstate = STATE_USB; if (!di->vbus_online) { di->vbus_online = 1; wake_lock(&usb_wake_lock); } } else { /* ensure we don't have a stale USB_EVENT_CHARGER should detect bounce */ di->usb_event = USB_EVENT_NONE; if (di->vbus_online) { di->vbus_online = 0; /* give USB and userspace some time to react before suspending */ wake_lock_timeout(&usb_wake_lock, HZ / 2); } } if (di->state == newstate) return; switch (newstate) { case STATE_FAULT: case STATE_BATTERY: if (is_charging(di)) twl6030_stop_usb_charger(di); break; case STATE_USB: case STATE_AC: /* moving out of STATE_FULL should only happen on unplug * or if we actually run down the battery capacity */ if (di->state == STATE_FULL) { newstate = STATE_FULL; break; } /* TODO: high current? */ if (!is_charging(di)) twl6030_start_usb_charger(di, 500); break; } if (di->state != newstate) { printk("battery: state %s -> %s\n", twl6030_state[di->state], twl6030_state[newstate]); di->state = newstate; power_supply_changed(&di->bat); power_supply_changed(&di->usb); } }
static int __devinit bq24157_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct bq24157_platform_data *pdata = client->dev.platform_data; printk("%s name : %s\n", __func__, client->name); /*First check the functionality supported by the host*/ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { printk("%s functionality check failed 1 \n", __func__); return -EIO; } if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) { printk("%s functionality check failed 2 \n", __func__); return -EIO; } if(bq24157_client == NULL) { bq24157_client = client; } else { printk("%s bq24157_client is not NULL. bq24157_client->name : %s\n", __func__, bq24157_client->name); ret = -ENXIO; goto err_bq24157_client_is_not_NULL; } #if defined(CONFIG_SPA) spa_external_event = spa_get_external_event_handler(); #endif ret = bq24157_read_chip_info(); if(ret) { printk("%s fail to read chip info\n", __func__); goto err_read_chip_info; } ret = bq24157_init_data(); if(ret) { printk("%s fail to init data\n", __func__); goto err_init_data; } if(pdata->cd == 0) { printk("%s please assign cd pin GPIO\n", __func__); ret = -1; goto err_gpio_request_cd; } ret = gpio_request(pdata->cd, "bq24157_CD"); if(ret) { dev_err(&client->dev,"bq24157: Unable to get gpio %d\n", pdata->cd); goto err_gpio_request_cd; } bq24157_chg_en = pdata->cd; #if defined(CONFIG_SPA) ret = spa_chg_register_enable_charge(bq24157_enable_charge); if(ret) { printk("%s fail to register enable_charge function\n", __func__); goto err_register_enable_charge; } ret = spa_chg_register_disable_charge(bq24157_disable_charge); if(ret) { printk("%s fail to register disable_charge function\n", __func__); goto err_register_disable_charge; } spa_external_event = spa_get_external_event_handler(); #endif INIT_DELAYED_WORK(&pdata->stat_irq_work, bq24157_stat_irq_work); wake_lock_init(&pdata->stat_irq_wakelock, WAKE_LOCK_SUSPEND, "bq24157_stat_irq"); if(client->irq){ printk("%s irq : %d\n", __func__, client->irq); /* check init status */ if((gpio_get_value(GPIO_IRQ(bq24157_client->irq))? 1 : 0) == 1) { wake_lock(&pdata->stat_irq_wakelock); schedule_delayed_work(&pdata->stat_irq_work, 0); } ret = gpio_request(GPIO_IRQ(client->irq), "bq24157_stat"); if(ret) { printk("%s gpio_request failed\n", __func__); goto err_gpio_request_bq24157_stat; } gpio_direction_input(GPIO_IRQ(client->irq)); ret = request_irq(client->irq, bq24157_stat_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "bq24157_stat", pdata); if(ret) { printk("%s request_irq failed\n", __func__); goto err_request_irq_bq24157_stat; } } return 0; err_request_irq_bq24157_stat: gpio_free(client->irq); err_gpio_request_bq24157_stat: #if defined(CONFIG_SPA) spa_chg_unregister_disable_charge(bq24157_disable_charge); err_register_disable_charge: spa_chg_unregister_enable_charge(bq24157_enable_charge); err_register_enable_charge: #endif err_gpio_request_cd: err_init_data: err_read_chip_info: #if defined(CONFIG_SPA) spa_external_event = NULL; #endif bq24157_client = NULL; err_bq24157_client_is_not_NULL: return ret; }
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; int wakeup_keys_status; int irq; static int irq_status = 1; struct gpio_kp *kp; struct gpio_event_matrix_info *mi; mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { /* TODO: disable scanning */ wakeup_keys_status = gpio_event_get_wakeup_keys_status() & 0x01; if (irq_status != wakeup_keys_status) { irq_status = wakeup_keys_status; } else { return 0; } for (i = 0; i < mi->ninputs; i++) { irq = gpio_to_irq(mi->input_gpios[i]); err = set_irq_wake(irq, irq_status); } /* HOME Key is wakeup source */ for (i = 0; i < mi->nwakeups; i++) { irq = gpio_to_irq(mi->wakeup_gpios[i]); err = set_irq_wake(irq, 1); } return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; pr_err("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } key_count = mi->ninputs * mi->noutputs; pgpio_key = *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_devs = input_devs; kp->keypad_info = mi; for (i = 0; i < key_count; i++) { unsigned short keyentry = mi->keymap[i]; unsigned short keycode = keyentry & MATRIX_KEY_MASK; unsigned short dev = keyentry >> MATRIX_CODE_BITS; if (dev >= input_devs->count) { pr_err("gpiomatrix: bad device index %d >= " "%d for key code %d\n", dev, input_devs->count, keycode); err = -EINVAL; goto err_bad_keymap; } if (keycode && keycode <= KEY_MAX) input_set_capability(input_devs->dev[dev], EV_KEY, keycode); } for (i = 0; i < mi->noutputs; i++) { err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (gpio_cansleep(mi->output_gpios[i])) { pr_err("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_output_gpio_configure_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE) err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); else err = gpio_direction_input(mi->output_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } err = gpio_direction_input(mi->input_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } kp->current_output = mi->noutputs; kp->key_state_changed = 1; hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->timer.function = gpio_keypad_timer_func; wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; kpd_dev = device_create(sec_class, NULL, 0, NULL, "sec_key"); if (!kpd_dev) printk("Failed to create device(sec_key)!\n"); if(device_create_file(kpd_dev, &dev_attr_key_pressed) < 0) printk("Failed to create file(%s)!\n", dev_attr_key_pressed.attr.name); pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " "%s%s in %s mode\n", input_devs->dev[0]->name, (input_devs->count > 1) ? "..." : "", kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); hrtimer_cancel(&kp->timer); wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } err_bad_keymap: kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }
void rk2918_get_charge_status(void) { int charge_on = 0; int tmp = get_msc_connect_flag(); int flag = dwc_vbus_status(); static char last_flag = 0; //printk("%s...........get_msc_connect_flag=%d,dwc_vbus_status=%d\n",__FUNCTION__,tmp,flag); #ifdef RK29_USB_CHARGE_SUPPORT if ((gpio_get_value(RK29_PIN0_PA0) == 0) &&(charge_on == 0) ) { //if (suspend_flag) return; #if 1 if (1 == flag) //USB PC { charge_on = 1; //printk("PC\n"); } else { if (2 == flag) //充电器 { charge_on = 1; //printk("charger\n"); } } #endif #if 0 if (usb_insert == 2) { charge_on = 1; //printk("%s.......charging with charger\n",__FUNCTION__); } #endif } #endif //printk("%s...dwc_vbus_status=%d,get_msc_connect_flag=%d\n",__FUNCTION__,dwc_vbus_status(),tmp); if (charge_on) { if((gBatChargeStatus !=1) || (last_flag != flag)) { gBatChargeStatus = 1; last_flag = flag; gBatStatusChangeCnt = 0; //状态变化开始计数 wake_lock(&battery_wake_lock); if (flag == 2) { rk2918_charge_enable(); } } } else { if(gBatChargeStatus != 0) { gBatChargeStatus = 0; gBatStatusChangeCnt = 0; //状态变化开始计数 wake_unlock(&battery_wake_lock); rk2918_charge_disable(); } } }
static int aic3254_set_config(int config_tbl, int idx, int en) { int len; struct ecodec_aic3254_state *drv = &codec_clk; pr_aud_info("%s: table(0x%X) index(%d)\n", __func__, config_tbl, idx); wake_lock(&drv->idlelock); #if defined(CONFIG_ARCH_MSM7X30) if (drv->enabled == 0) { /* enable MI2S RX master block */ /* enable MI2S RX bit clock */ clk_enable(drv->rx_mclk); clk_enable(drv->rx_sclk); printk("%s: enable CLK\n", __func__); drv->enabled = 1; } #endif switch (config_tbl) { case AIC3254_CONFIG_TX: /* TX */ pr_aud_info("%s: enable tx\n", __func__); #if defined(CONFIG_SPI_AIC3254_SELF_POWER_DOWN) if (en && idx != UPLINK_OFF) { #else if (en) { #endif if (ctl_ops->tx_amp_enable) ctl_ops->tx_amp_enable(0); aic3254_tx_config(idx); aic3254_tx_mode = idx; if (ctl_ops->tx_amp_enable) ctl_ops->tx_amp_enable(1); } else { aic3254_tx_config(UPLINK_OFF); aic3254_tx_mode = UPLINK_OFF; #if defined(CONFIG_SPI_AIC3254_SELF_POWER_DOWN) if (ctl_ops->tx_amp_enable) ctl_ops->tx_amp_enable(0); aic3254_powerdown(); #endif } break; case AIC3254_CONFIG_RX: /* RX */ pr_aud_info("%s: enable rx\n", __func__); #if defined(CONFIG_SPI_AIC3254_SELF_POWER_DOWN) if (en && idx != DOWNLINK_OFF) { #else if (en) { #endif if (ctl_ops->rx_amp_enable) ctl_ops->rx_amp_enable(0); aic3254_rx_config(idx); aic3254_rx_mode = idx; if (ctl_ops->rx_amp_enable) ctl_ops->rx_amp_enable(1); } else { aic3254_rx_config(DOWNLINK_OFF); aic3254_rx_mode = DOWNLINK_OFF; #if defined(CONFIG_SPI_AIC3254_SELF_POWER_DOWN) if (ctl_ops->rx_amp_enable) ctl_ops->rx_amp_enable(0); aic3254_powerdown(); #endif } break; case AIC3254_CONFIG_MEDIA: if (aic3254_minidsp == NULL) return -EFAULT; len = (aic3254_minidsp[idx][0].reg << 8) | aic3254_minidsp[idx][0].data; pr_aud_info("%s: miniDSP command len = %d\n", __func__, len); pr_aud_info("%s: rx mode %d, tx mode %d\n", __func__, aic3254_rx_mode, aic3254_tx_mode); if (ctl_ops->rx_amp_enable) ctl_ops->rx_amp_enable(0); /* step 1: power off first */ if (aic3254_rx_mode != DOWNLINK_OFF) aic3254_rx_config(DOWNLINK_OFF); /* step 2: config DSP */ aic3254_config(&aic3254_minidsp[idx][1], len); /* step 3: switch back to original path */ if (aic3254_rx_mode != DOWNLINK_OFF) aic3254_rx_config(aic3254_rx_mode); if (aic3254_tx_mode != UPLINK_OFF) aic3254_tx_config(aic3254_tx_mode); if (ctl_ops->rx_amp_enable) ctl_ops->rx_amp_enable(1); pr_aud_info("%s: configure minidsp done\n", __func__); break; } wake_unlock(&drv->idlelock); return 0; } static int aic3254_open(struct inode *inode, struct file *pfile) { int ret = 0; mutex_lock(&lock); if (aic3254_opend) { pr_aud_err("%s: busy\n", __func__); ret = -EBUSY; } else aic3254_opend = 1; mutex_unlock(&lock); return ret; } static int aic3254_release(struct inode *inode, struct file *pfile) { mutex_lock(&lock); aic3254_opend = 0; mutex_unlock(&lock); return 0; }