void dpi_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { u32 irq; static struct pm_qos_request_list *qos_request; dssdev->panel.timings = *timings; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { if (dssdev->channel == OMAP_DSS_CHANNEL_LCD) { irq = DISPC_IRQ_VSYNC; } else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) { irq = DISPC_IRQ_VSYNC2; } else { DSSDBG("dpi_set_timings: error, display channel not supported"); return; } omap_pm_set_max_mpu_wakeup_lat(&qos_request, 0); omap_dispc_run_on_irq(irq, on_isr_set_timings, dssdev); omap_dispc_run_on_irq(irq, on_isr_issue_go, dssdev); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); } else { DSSDBG("dpi_set_timings: error; panel not active\n"); } }
int sdp3430_i2s_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; /* * Hold C2 as min latency constraint. Deeper states * MPU RET/OFF is overhead and consume more power than * savings. * snd_hw_latency check takes care of playback and capture * usecase. */ if (!snd_hw_latency++) { omap_pm_set_max_mpu_wakeup_lat(&substream->latency_pm_qos_req, 18); /* * As of now for MP3 playback case need to enable dpll3 * autoidle part of dpll3 lock errata. * REVISIT: Remove this, Once the dpll3 lock errata is * updated with with a new workaround without impacting mp3 usecase. */ printk("sdp3430_i2s_startup \n"); omap_dpll3_errat_wa(0); } return 0; }
int sdp3430_i2s_shutdown(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; /* remove latency constraint */ snd_hw_latency--; if (!snd_hw_latency) { omap_pm_set_max_mpu_wakeup_lat(&substream->latency_pm_qos_req, -1); printk("sdp3430_i2s_shutdown \n"); omap_dpll3_errat_wa(1); } return 0; }
/** * sr_class1p5_enable() - class 1.5 mode of enable * @voltdm: voltage domain to enable SR for * @volt_data: voltdata to the voltage transition taking place * * when this gets called, we use the h/w loop to setup our voltages * to an calibrated voltage, detect any oscillations, recover from the same * and finally store the optimized voltage as the calibrated voltage in the * system */ static int sr_class1p5_enable(struct voltagedomain *voltdm, struct omap_volt_data *volt_data) { int r; struct sr_class1p5_work_data *work_data; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(volt_data)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } /* if already calibrated, nothing to do here.. */ if (volt_data->volt_calibrated) return 0; work_data = get_sr1p5_work(voltdm); if (unlikely(!work_data)) { pr_err("%s: aieeee.. bad work data??\n", __func__); return -EINVAL; } if (work_data->work_active) return 0; omap_vp_enable(voltdm); r = sr_enable(voltdm, volt_data); if (r) { pr_err("%s: sr[%s] failed\n", __func__, voltdm->name); omap_vp_disable(voltdm); return r; } work_data->vdata = volt_data; work_data->work_active = true; work_data->num_calib_triggers = 0; /* Hold a c-state constraint */ omap_pm_set_max_mpu_wakeup_lat(&work_data->qos_request, 1000); pr_debug("%s - %s: hold c-state\n", __func__, voltdm->name); /* program the workqueue and leave it to calibrate offline.. */ schedule_delayed_work(&work_data->work, msecs_to_jiffies(SR1P5_SAMPLING_DELAY_MS * SR1P5_STABLE_SAMPLES)); return 0; }
/** * sr_class1p5_disable() - disable for class 1p5 * @voltdm: voltage domain for the sr which needs disabling * @volt_data: voltagedata to disable * @is_volt_reset: reset the voltage? * * we dont do anything if the class 1p5 is being used. this is because we * already disable sr at the end of calibration and no h/w loop is actually * active when this is called. */ static int sr_class1p5_disable(struct voltagedomain *voltdm, struct omap_volt_data *volt_data, int is_volt_reset) { struct sr_class1p5_work_data *work_data; if (IS_ERR_OR_NULL(voltdm) || IS_ERR_OR_NULL(volt_data)) { pr_err("%s: bad parameters!\n", __func__); return -EINVAL; } work_data = get_sr1p5_work(voltdm); if (work_data->work_active) { /* if volt reset and work is active, we dont allow this */ if (is_volt_reset) return -EBUSY; /* flag work is dead and remove the old work */ work_data->work_active = false; cancel_delayed_work_sync(&work_data->work); sr_notifier_control(voltdm, false); omap_vp_disable(voltdm); sr_disable(voltdm); /* Release c-state constraint */ omap_pm_set_max_mpu_wakeup_lat(&work_data->qos_request, -1); pr_debug("%s - %s: release c-state\n", __func__, voltdm->name); } /* if already calibrated, nothin special to do here.. */ if (volt_data->volt_calibrated) return 0; if (is_volt_reset) omap_voltage_reset(voltdm); return 0; }
/* blocking notifier support */ void cpcap_musb_notifier_call(unsigned long event) { struct musb *musb = g_musb; struct device *dev = musb->controller; struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; static int hostmode; u32 val; u8 power; switch (event) { case USB_EVENT_ID: DBG(1, "ID GND\n"); /* configure musb into smartidle with wakeup enabled * smart standby mode. */ omap_pm_set_max_mpu_wakeup_lat(&pdata->musb_qos_request, 4000); musb_writel(musb->mregs, OTG_FORCESTDBY, 0); val = musb_readl(musb->mregs, OTG_SYSCONFIG); if (cpu_is_omap44xx()) val |= SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP; else val |= SMARTIDLE | SMARTSTDBY | ENABLEWAKEUP; musb_writel(musb->mregs, OTG_SYSCONFIG, val); if (data->interface_type == MUSB_INTERFACE_UTMI) { phy_init(); otg_init(musb->xceiv); /* enable VBUS valid, id groung*/ __raw_writel(AVALID | VBUSVALID, ctrl_base + USBOTGHS_CONTROL); val = __raw_readl(phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); val |= DP_WAKEUPENABLE; __raw_writel(val, phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); } hostmode = 1; musb_start(musb); musb_set_vbus(musb, 1); break; case USB_EVENT_VBUS: DBG(1, "VBUS Connect\n"); /* configure musb into smartidle with wakeup enabled * smart standby mode. */ musb_writel(musb->mregs, OTG_FORCESTDBY, 0); val = musb_readl(musb->mregs, OTG_SYSCONFIG); if (cpu_is_omap44xx()) val |= SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP; else val |= SMARTIDLE | SMARTSTDBY | ENABLEWAKEUP; musb_writel(musb->mregs, OTG_SYSCONFIG, val); power = musb_readb(musb->mregs, MUSB_POWER); power &= ~MUSB_POWER_SOFTCONN; musb_writeb(musb->mregs, MUSB_POWER, power); if (data->interface_type == MUSB_INTERFACE_UTMI) { phy_init(); otg_init(musb->xceiv); if (!hostmode) { /* Enable VBUS Valid, AValid. Clear SESSEND.*/ __raw_writel(IDDIG | AVALID | VBUSVALID, ctrl_base + USBOTGHS_CONTROL); } } break; case USB_EVENT_NONE: DBG(1, "VBUS Disconnect\n"); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* enable this clock because in suspend interrupt * handler phy clocks are disabled. If phy clocks are * not enabled then DISCONNECT interrupt will not be * reached to mentor */ otg_set_clk(musb->xceiv, 1); __raw_writel(SESSEND | IDDIG, ctrl_base + USBOTGHS_CONTROL); if (musb->xceiv->set_vbus) otg_set_vbus(musb->xceiv, 0); otg_shutdown(musb->xceiv); phy_shutdown(); } /* configure in force idle/ standby */ musb_writel(musb->mregs, OTG_FORCESTDBY, 1); val = musb_readl(musb->mregs, OTG_SYSCONFIG); val &= ~(SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP); val |= FORCEIDLE | FORCESTDBY; musb_writel(musb->mregs, OTG_SYSCONFIG, val); omap_pm_set_max_mpu_wakeup_lat(&pdata->musb_qos_request, -1); if (data->interface_type == MUSB_INTERFACE_UTMI) { val = __raw_readl(phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); val &= ~DP_WAKEUPENABLE; __raw_writel(val, phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); } if (hostmode) { musb_stop(musb); musb_set_vbus(musb, 0); } hostmode = 0; break; default: DBG(1, "ID float\n"); } }
/* * Low level master read/write transaction. */ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) { struct omap_i2c_dev *dev = i2c_get_adapdata(adap); int r; u16 w; dev_dbg(dev->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", msg->addr, msg->len, msg->flags, stop); if (msg->len == 0) return -EINVAL; omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr); /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ dev->buf = msg->buf; dev->buf_len = msg->len; omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); /* Clear the FIFO Buffers */ w = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR; omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w); init_completion(&dev->cmd_complete); dev->cmd_err = 0; w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; /* High speed configuration */ if (dev->speed > 400) w |= OMAP_I2C_CON_OPMODE_HS; if (msg->flags & I2C_M_TEN) w |= OMAP_I2C_CON_XA; if (!(msg->flags & I2C_M_RD)) w |= OMAP_I2C_CON_TRX; if (!dev->b_hw && stop) w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); /* * Don't write stt and stp together on some hardware. */ if (dev->b_hw && stop) { unsigned long delay = jiffies + OMAP_I2C_TIMEOUT; u16 con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); while (con & OMAP_I2C_CON_STT) { con = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); /* Let the user know if i2c is in a bad state */ if (time_after(jiffies, delay)) { dev_err(dev->dev, "controller timed out " "waiting for start condition to finish\n"); return -ETIMEDOUT; } cpu_relax(); } /* FIXME: should consider ARDY value before writing to I2C_CON */ w |= OMAP_I2C_CON_STP; w &= ~OMAP_I2C_CON_STT; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } /* * REVISIT: We should abort the transfer on signals, but the bus goes * into arbitration and we're currently unable to recover from it. */ /* * REVISIT: Add a mpu wake-up latency constraint to let us wake * quickly enough for i2c transfers to work properly. Should change * the code to use a latency constraint function passed from pdata. */ omap_pm_set_max_mpu_wakeup_lat(dev->dev, 500); r = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); omap_pm_set_max_mpu_wakeup_lat(dev->dev, -1); dev->buf_len = 0; if (r < 0) return r; if (r == 0) { dev_err(dev->dev, "controller timed out\n"); omap_i2c_init(dev); return -ETIMEDOUT; } if (likely(!dev->cmd_err)) return 0; /* We have an error */ if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { omap_i2c_init(dev); return -EIO; } if (dev->cmd_err & OMAP_I2C_STAT_NACK) { if (msg->flags & I2C_M_IGNORE_NAK) return 0; if (stop) { w = omap_i2c_read_reg(dev, OMAP_I2C_CON_REG); w |= OMAP_I2C_CON_STP; omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, w); } return -EREMOTEIO; } return -EIO; }
static int yacd5b1s_sensor_power_set(struct v4l2_int_device *dev, enum v4l2_power power) { struct omap34xxcam_videodev *vdev = dev->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); static enum v4l2_power previous_power = V4L2_POWER_OFF; //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] [2011.07.26] - CAM // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [START] static struct pm_qos_request_list *qos_request; // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [END] //--]] LGE_UBIQUIX_MODIFIED_END : [email protected] [2011.07.26] - CAM int err = 0; switch (power) { case V4L2_POWER_ON: /* Power Up Sequence */ printk(KERN_DEBUG "yacd5b1s_sensor_power_set(ON)\n"); omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 800000); /* Hold a constraint to keep MPU in C1 */ //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] [2011.07.26] - CAM // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [START] //omap_pm_set_max_mpu_wakeup_lat(vdev->cam->isp, 12); omap_pm_set_max_mpu_wakeup_lat(&qos_request, 12); // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [END] //--]] LGE_UBIQUIX_MODIFIED_END : [email protected] [2011.07.26] - CAM isp_configure_interface(vdev->cam->isp,&yacd5b1s_if_config); if (gpio_request(YACD5B1S_RESET_GPIO, "yacd5b1s_rst") != 0) printk("\n\n\n>>>>>>>>>>>>YACD5B1S_RESET_GPIO_gpio_request_error\n\n\n");//return -EIO; if (gpio_request(YACD5B1S_STANDBY_GPIO, "yacd5b1s_PWD") != 0) printk("\n\n\n>>>>>>>>>>>>YACD5B1S_STANDBY_GPIO_gpio_request_error\n\n\n");//return -EIO;return -EIO; #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, SET_VMMC1_V2_8,VMMC1_DEDICATED ); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VMMC1_DEV_GRP_P1,VMMC1_DEV_GRP ); #endif udelay(20); #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX3_1_8_V, TWL4030_VAUX3_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX3_DEV_GRP); #endif twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_1_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); //wait typical 500ms for xclk to settle //mdelay(500); gpio_direction_output(YACD5B1S_STANDBY_GPIO, true); udelay(100); gpio_set_value(YACD5B1S_STANDBY_GPIO, 0); udelay(1500); gpio_set_value(YACD5B1S_STANDBY_GPIO, 1); mdelay(100); udelay(50); gpio_direction_output(YACD5B1S_RESET_GPIO, true); udelay(100); gpio_set_value(YACD5B1S_RESET_GPIO, 0); /* set to output mode */ udelay(1500); gpio_set_value(YACD5B1S_RESET_GPIO, 1); udelay(300); break; case V4L2_POWER_OFF: printk(KERN_DEBUG "yacd5b1s_sensor_power_set(OFF)\n"); /* Power Down Sequence */ gpio_set_value(YACD5B1S_RESET_GPIO, 0); udelay(50); gpio_set_value(YACD5B1S_STANDBY_GPIO, 0); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE,VMMC1_DEV_GRP ); #endif #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX3_DEV_GRP); #endif gpio_free(YACD5B1S_STANDBY_GPIO); gpio_free(YACD5B1S_RESET_GPIO); omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, -1); //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] [2011.07.26] - CAM // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [START] //omap_pm_set_max_mpu_wakeup_lat(vdev->cam->isp, -1); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [END] //--]] LGE_UBIQUIX_MODIFIED_END : [email protected] [2011.07.26] - CAM if (previous_power == V4L2_POWER_ON){ isp_disable_mclk(isp); udelay(5); } break; case V4L2_POWER_STANDBY: printk(KERN_DEBUG "yacd5b1s_sensor_power_set(STANDBY)\n"); gpio_set_value(YACD5B1S_RESET_GPIO, 0); udelay(50); gpio_set_value(YACD5B1S_STANDBY_GPIO, 0); udelay(50); gpio_free(YACD5B1S_STANDBY_GPIO); gpio_free(YACD5B1S_RESET_GPIO); if (previous_power == V4L2_POWER_ON){ isp_disable_mclk(isp); udelay(5); } break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return err; }
static int gc2015_sensor_power_set(struct v4l2_int_device *s, enum v4l2_power power) { struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); static enum v4l2_power previous_power = V4L2_POWER_OFF; static struct pm_qos_request_list *qos_request; int err = 0; printk(KERN_INFO "previous_power = %d,gc2015_sensor_power_set(%d)\n",previous_power,power); switch (power) { case V4L2_POWER_ON: /* Through-put requirement: * 3280 x 2464 x 2Bpp x 7.5fps x 3 memory ops = 355163 KByte/s */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 664000); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(&qos_request, 12); isp_configure_interface(vdev->cam->isp,&gc2015_if_config); udelay(20); //#ifndef KUNLUN_P0 jhy close according to cam poweron timing //gpio_direction_output(GC2015_STANDBY_GPIO, 0); //udelay(10); //#endif // gpio_direction_output(GC2015_RESET_GPIO, 0); /* turn on analog & IO power jhy add VAUX3 Ctrl 2011.6.30*/ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX3_1_8_V, TWL4030_VAUX3_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX3_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX2_1_5_V, TWL4030_VAUX2_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX2_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_2_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); udelay(100); printk(KERN_INFO "VAUX4 = 2.8V\n"); /*jhy add according to cam poweron timing beg 2011.6.30*/ #if 1 /*defined CONFIG_CAM_GPIO_I2C*/ gpio_direction_output(CAM_SCL_GPIO, 1); gpio_direction_output(CAM_SDA_GPIO, 1); #endif gpio_direction_output(GC2015_STANDBY_GPIO, 0); //standby /*jhy add according to cam poweron timing end 2011.6.30*/ /* have to put sensor to reset to guarantee detection */ gpio_direction_output(GC2015_RESET_GPIO, 0); udelay(1500); /* nRESET is active LOW. set HIGH to release reset */ gpio_direction_output(GC2015_RESET_GPIO, 1); printk(KERN_INFO "reset camera\n"); break; case V4L2_POWER_OFF: printk(KERN_INFO "GC2015_sensor_power_set(OFF)\n"); case V4L2_POWER_STANDBY: printk(KERN_INFO "GC2015_sensor_power_set(STANDBY)\n"); #ifndef KUNLUN_P0 /*kunlun P0 can't use GC2015_STANDBY_GPIO*/ gpio_direction_output(GC2015_STANDBY_GPIO, 0); //1 change by jhy for IOVDD has been close so standby no use 2011.6.30 udelay(20); gpio_direction_output(GC2015_RESET_GPIO, 0); udelay(20); //printk(KERN_DEBUG "GC2015_sensor_power_set(STANDBY)\n"); #endif /* Remove pm constraints */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); /*jhy add according to cam poweron timing beg 2011.6.30*/ #if 1 /*definded CONFIG_CAM_GPIO_I2C*/ gpio_direction_output(CAM_SCL_GPIO, 0); gpio_direction_output(CAM_SDA_GPIO, 0); #endif /*jhy add according to cam poweron timing end 2011.6.30*/ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX2_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX3_DEV_GRP); //jhy add for Cam IOVDD ctrl 2011.6.30 /* Make sure not to disable the MCLK twice in a row */ if (previous_power == V4L2_POWER_ON) isp_disable_mclk(isp); break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return err; }
/** * do_calibrate() - work which actually does the calibration * @work: pointer to the work * * calibration routine uses the following logic: * on the first trigger, we start the isr to collect sr voltages * wait for stabilization delay (reschdule self instead of sleeping) * after the delay, see if we collected any isr events * if none, we have calibrated voltage. * if there are any, we retry untill we giveup. * on retry timeout, select a voltage to use as safe voltage. */ static void do_calibrate(struct work_struct *work) { struct sr_class1p5_work_data *work_data = container_of(work, struct sr_class1p5_work_data, work.work); unsigned long u_volt_safe = 0, u_volt_current = 0; struct omap_volt_data *volt_data; struct voltagedomain *voltdm; if (unlikely(!work_data)) { pr_err("%s: ooops.. null work_data?\n", __func__); return; } /* * Handle the case where we might have just been scheduled AND * 1.5 disable was called. */ if (omap_vscale_pause(work_data->voltdm, true)) { schedule_delayed_work(&work_data->work, msecs_to_jiffies(SR1P5_SAMPLING_DELAY_MS * SR1P5_STABLE_SAMPLES)); return; } voltdm = work_data->voltdm; /* * In the unlikely case that we did get through when unplanned, * flag and return. */ if (unlikely(!work_data->work_active)) { pr_err("%s:%s unplanned work invocation!\n", __func__, voltdm->name); omap_vscale_unpause(work_data->voltdm); return; } work_data->num_calib_triggers++; /* if we are triggered first time, we need to start isr to sample */ if (work_data->num_calib_triggers == 1) goto start_sampling; /* Stop isr from interrupting our measurements :) */ sr_notifier_control(voltdm, false); volt_data = work_data->vdata; /* if there are no samples captured.. SR is silent, aka stability! */ if (!work_data->num_osc_samples) { u_volt_safe = omap_vp_get_curr_volt(voltdm); u_volt_current = u_volt_safe; goto done_calib; } if (work_data->num_calib_triggers == SR1P5_MAX_TRIGGERS) { pr_warning("%s: %s recalib timeout!\n", __func__, work_data->voltdm->name); goto oscillating_calib; } /* we have potential oscillations/first sample */ start_sampling: work_data->num_osc_samples = 0; /* Clear pending events */ sr_notifier_control(voltdm, false); /* Clear all transdones */ while (omap_vp_is_transdone(voltdm)) omap_vp_clear_transdone(voltdm); /* trigger sampling */ sr_notifier_control(voltdm, true); schedule_delayed_work(&work_data->work, msecs_to_jiffies(SR1P5_SAMPLING_DELAY_MS * SR1P5_STABLE_SAMPLES)); omap_vscale_unpause(work_data->voltdm); return; oscillating_calib: /* Use the nominal voltage as the safe voltage */ u_volt_safe = volt_data->volt_nominal; /* pick up current voltage to switch if needed */ u_volt_current = omap_vp_get_curr_volt(voltdm); /* Fall through to close up common stuff */ done_calib: omap_vp_disable(voltdm); sr_disable(voltdm); volt_data->volt_calibrated = u_volt_safe; /* Setup my dynamic voltage for the next calibration for this opp */ volt_data->volt_dynamic_nominal = omap_get_dyn_nominal(volt_data); /* * if the voltage we decided as safe is not the current voltage, * switch */ if (cpu_is_omap3630()) { pr_debug("%s:%s - sr opp margin %d\n", __func__, voltdm->name, volt_data->sr_oppmargin); volt_data->volt_calibrated += volt_data->sr_oppmargin; if (volt_data->volt_calibrated > volt_data->volt_nominal) { volt_data->volt_calibrated = volt_data->volt_nominal; } } if (volt_data->volt_calibrated != u_volt_current) { pr_debug("%s:%s reconfiguring to voltage %d\n", __func__, voltdm->name, volt_data->volt_calibrated); omap_voltage_scale_vdd(voltdm, volt_data); } /* * TODO: Setup my wakeup voltage to allow immediate going to OFF and * on - Pending twl and voltage layer cleanups. * This is necessary, as this is not done as part of regular * Dvfs flow. * vc_setup_on_voltage(voltdm, volt_data->volt_calibrated); */ work_data->work_active = false; omap_vscale_unpause(work_data->voltdm); /* Release c-state constraint */ omap_pm_set_max_mpu_wakeup_lat(&work_data->qos_request, -1); pr_debug("%s - %s: release c-state\n", __func__, voltdm->name); }
static int mt9p012_sensor_power_set(struct device *dev, enum v4l2_power power) { static struct regulator *regulator; int error = 0; switch (power) { case V4L2_POWER_OFF: /* Power Down Sequence */ gpio_direction_output(GPIO_MT9P012_RESET, 0); gpio_free(GPIO_MT9P012_RESET); /* Turn off power */ if (regulator != NULL) { regulator_disable(regulator); regulator_put(regulator); regulator = NULL; } else { sholes_camera_lines_safe_mode(); pr_err("%s: Regulator for vcam is not "\ "initialized\n", __func__); return -EIO; } /* Release pm constraints */ omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(dev, -1); sholes_camera_lines_safe_mode(); break; case V4L2_POWER_ON: if (previous_power == V4L2_POWER_OFF) { /* Power Up Sequence */ sholes_camera_lines_func_mode(); /* Set min throughput to: * 2592 x 1944 x 2bpp x 30fps x 3 L3 accesses */ omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, 885735); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(dev, MPU_LATENCY_C1); /* Configure ISP */ isp_configure_interface(&mt9p012_if_config); /* Request and configure gpio pins */ if (gpio_request(GPIO_MT9P012_RESET, "mt9p012 camera reset") != 0) { error = -EIO; goto out; } /* set to output mode */ gpio_direction_output(GPIO_MT9P012_RESET, 0); /* nRESET is active LOW. set HIGH to release reset */ gpio_set_value(GPIO_MT9P012_RESET, 1); /* turn on digital power */ if (regulator != NULL) { pr_warning("%s: Already have "\ "regulator\n", __func__); } else { regulator = regulator_get(NULL, "vcam"); if (IS_ERR(regulator)) { pr_err("%s: Cannot get vcam "\ "regulator, err=%ld\n", __func__, PTR_ERR(regulator)); error = PTR_ERR(regulator); goto out; } } if (regulator_enable(regulator) != 0) { pr_err("%s: Cannot enable vcam regulator\n", __func__); error = -EIO; goto out; } } udelay(1000); if (previous_power == V4L2_POWER_OFF) { /* trigger reset */ gpio_direction_output(GPIO_MT9P012_RESET, 0); udelay(1500); /* nRESET is active LOW. set HIGH to release reset */ gpio_set_value(GPIO_MT9P012_RESET, 1); /* give sensor sometime to get out of the reset. * Datasheet says 2400 xclks. At 6 MHz, 400 usec is * enough */ udelay(300); } break; out: omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(dev, -1); sholes_camera_lines_safe_mode(); return error; case V4L2_POWER_STANDBY: /* Stand By Sequence */ break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return 0; }
static int S5K5CA_sensor_power_set(struct v4l2_int_device *s, enum v4l2_power power) { struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); static enum v4l2_power previous_power = V4L2_POWER_OFF; static struct pm_qos_request_list *qos_request; int err = 0; printk(KERN_INFO "previous_power = %d,S5K5CA_sensor_power_set(%d)\n",previous_power,power); switch (power) { case V4L2_POWER_ON: /* Through-put requirement: * 3280 x 2464 x 2Bpp x 7.5fps x 3 memory ops = 355163 KByte/s */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 664000); // 276480); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(&qos_request, 12); isp_configure_interface(vdev->cam->isp,&S5K5CA_if_config); /* turn on analog power */ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX2_1_5_V, TWL4030_VAUX2_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX2_DEV_GRP); udelay(600); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_2_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); udelay(100); printk(KERN_INFO "VAUX4 = 2.8V\n"); gpio_direction_output(S5K5CA_RESET_GPIO, 0); printk(KERN_INFO "reset camera\n"); udelay(20); gpio_direction_output(S5K5CA_STANDBY_GPIO, 1); udelay(20); gpio_direction_output(S5K5CA_RESET_GPIO, 1); //udelay(20); break; case V4L2_POWER_OFF: printk(KERN_INFO "S5K5CA_sensor_power_set(OFF)\n"); break; case V4L2_POWER_STANDBY: printk(KERN_INFO "S5K5CA_sensor_power_set(STANDBY)\n"); /* Remove pm constraints */ gpio_direction_output(S5K5CA_STANDBY_GPIO, 0); mdelay(50); omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX2_DEV_GRP); /* Make sure not to disable the MCLK twice in a row */ if (previous_power == V4L2_POWER_ON) isp_disable_mclk(isp); break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return err; }
static int ov2659_sensor_power_set(struct v4l2_int_device *s, enum v4l2_power power) { struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); static enum v4l2_power previous_power = V4L2_POWER_OFF; static struct pm_qos_request_list *qos_request; int err = 0; printk(KERN_INFO "previous_power = %d,ov2659_sensor_power_set(%d)\n",previous_power,power); switch (power) { case V4L2_POWER_ON: /* Through-put requirement: * 3280 x 2464 x 2Bpp x 7.5fps x 3 memory ops = 355163 KByte/s */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 664000); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(&qos_request, 12); isp_configure_interface(vdev->cam->isp,&ov2659_if_config); udelay(20); #if OV2659_USE_STANDBY //add standby mode for cam open speed up jhy 2011.09.09 if (previous_power == V4L2_POWER_OFF) { gpio_direction_output(OV2659_STANDBY_GPIO, 0); //standby gpio_direction_output(OV2659_RESET_GPIO, 1); /* turn on analog & IO power jhy add VAUX3 Ctrl 2011.6.30*/ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX3_1_8_V, TWL4030_VAUX3_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX3_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, TWL4030_VAUX_REMAP_VALUE, TWL4030_VAUX3_REMAP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX2_1_5_V, TWL4030_VAUX2_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX2_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, TWL4030_VAUX_REMAP_VALUE, TWL4030_VAUX2_REMAP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_2_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, TWL4030_VAUX_REMAP_VALUE, TWL4030_VAUX4_REMAP); udelay(100); //printk(KERN_INFO "VAUX4 = 2.8V\n"); /* have to put sensor to reset to guarantee detection */ gpio_direction_output(OV2659_RESET_GPIO, 0); udelay(1500); /* nRESET is active LOW. set HIGH to release reset */ gpio_direction_output(OV2659_RESET_GPIO, 1); } else { gpio_direction_output(OV2659_STANDBY_GPIO, 0); printk(KERN_INFO "camera(OV2659) exit standby\n"); } #else gpio_direction_output(OV2659_STANDBY_GPIO, 0); //standby gpio_direction_output(OV2659_RESET_GPIO, 1); /* turn on analog & IO power jhy add VAUX3 Ctrl 2011.6.30*/ twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX3_1_8_V, TWL4030_VAUX3_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX3_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX2_1_5_V, TWL4030_VAUX2_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX2_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_2_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); udelay(100); //printk(KERN_INFO "VAUX4 = 2.8V\n"); /* have to put sensor to reset to guarantee detection */ gpio_direction_output(OV2659_RESET_GPIO, 0); udelay(1500); /* nRESET is active LOW. set HIGH to release reset */ gpio_direction_output(OV2659_RESET_GPIO, 1); #endif //printk(KERN_INFO "reset camera\n"); break; case V4L2_POWER_OFF: printk(KERN_INFO "OV2659_sensor_power_set(OFF)\n"); case V4L2_POWER_STANDBY: /* Remove pm constraints */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); #if OV2659_USE_STANDBY // standby mode for cam jhy 2011.09.09 gpio_direction_output(OV2659_STANDBY_GPIO, 1); #else gpio_direction_output(OV2659_STANDBY_GPIO, 0); gpio_direction_output(OV2659_RESET_GPIO, 0); #if 1 /*definded CONFIG_CAM_GPIO_I2C */ gpio_direction_output(CAM_SCL_GPIO, 0); gpio_direction_output(CAM_SDA_GPIO, 0); #endif twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX2_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX3_DEV_GRP); //jhy add for Cam IOVDD ctrl 2011.6.30 #endif /* Make sure not to disable the MCLK twice in a row */ if (previous_power == V4L2_POWER_ON) isp_disable_mclk(isp); break; } #if !OV2659_USE_STANDBY /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; #endif return err; }
/* blocking notifier support */ int musb_notifier_call(struct notifier_block *nb, unsigned long event, void *unused) { struct musb *musb = container_of(nb, struct musb, nb); struct device *dev = musb->controller; struct musb_hdrc_platform_data *pdata = dev->platform_data; struct omap_musb_board_data *data = pdata->board_data; static struct pm_qos_request_list *usb_qos_request; static int hostmode; u32 val; switch (event) { case USB_EVENT_ID: DBG(1, "ID GND\n"); /* configure musb into smartidle with wakeup enabled * smart standby mode. */ wake_lock(&usb_lock); omap_pm_set_max_mpu_wakeup_lat(&usb_qos_request, 4000); musb_writel(musb->mregs, OTG_FORCESTDBY, 0); val = musb_readl(musb->mregs, OTG_SYSCONFIG); if (cpu_is_omap44xx()) val |= SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP; else val |= SMARTIDLE | SMARTSTDBY | ENABLEWAKEUP; musb_writel(musb->mregs, OTG_SYSCONFIG, val); if (data->interface_type == MUSB_INTERFACE_UTMI) { otg_init(musb->xceiv); hostmode = 1; musb_enable_vbus(musb); } if (pdata->set_min_bus_tput) pdata->set_min_bus_tput(musb->controller, OCP_INITIATOR_AGENT, (200*1000*4)); val = __raw_readl(phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); val |= DP_WAKEUPENABLE; __raw_writel(val, phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); break; case USB_EVENT_VBUS: DBG(1, "VBUS Connect\n"); usb_gadget_vbus_connect(&musb->g); wake_lock(&usb_lock); /* configure musb into smartidle with wakeup enabled * smart standby mode. */ musb_writel(musb->mregs, OTG_FORCESTDBY, 0); val = musb_readl(musb->mregs, OTG_SYSCONFIG); if (cpu_is_omap44xx()) val |= SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP; else val |= SMARTIDLE | SMARTSTDBY | ENABLEWAKEUP; musb_writel(musb->mregs, OTG_SYSCONFIG, val); if (data->interface_type == MUSB_INTERFACE_UTMI) { otg_init(musb->xceiv); if (!hostmode) { /* Enable VBUS Valid, AValid. Clear SESSEND.*/ __raw_writel(IDDIG | AVALID | VBUSVALID, ctrl_base + USBOTGHS_CONTROL); } } /* hold the L3 constraint as there was performance drop with * ondemand governor */ if (pdata->set_min_bus_tput) pdata->set_min_bus_tput(musb->controller, OCP_INITIATOR_AGENT, (200*1000*4)); break; case USB_EVENT_NONE: DBG(1, "VBUS Disconnect\n"); usb_gadget_vbus_disconnect(&musb->g); if (data->interface_type == MUSB_INTERFACE_UTMI) { /* enable this clock because in suspend interrupt * handler phy clocks are disabled. If phy clocks are * not enabled then DISCONNECT interrupt will not be * reached to mentor */ otg_set_clk(musb->xceiv, 1); __raw_writel(SESSEND | IDDIG, ctrl_base + USBOTGHS_CONTROL); if (musb->xceiv->set_vbus) otg_set_vbus(musb->xceiv, 0); otg_shutdown(musb->xceiv); } hostmode = 0; /* configure in force idle/ standby */ musb_writel(musb->mregs, OTG_FORCESTDBY, 1); val = musb_readl(musb->mregs, OTG_SYSCONFIG); val &= ~(SMARTIDLEWKUP | SMARTSTDBY | ENABLEWAKEUP); val |= FORCEIDLE | FORCESTDBY; musb_writel(musb->mregs, OTG_SYSCONFIG, val); wake_unlock(&usb_lock); /* Release L3 constraint */ if (pdata->set_min_bus_tput) pdata->set_min_bus_tput(musb->controller, OCP_INITIATOR_AGENT, -1); val = __raw_readl(phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); val &= ~DP_WAKEUPENABLE; __raw_writel(val, phymux_base + USBA0_OTG_CE_PAD1_USBA0_OTG_DP); break; default: DBG(1, "ID float\n"); return NOTIFY_DONE; } return NOTIFY_OK; }
/* * XXX This function is a temporary compatibility wrapper - only * needed until the I2C driver can be converted to call * omap_pm_set_max_dev_wakeup_lat() and handle a return code. */ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) { omap_pm_set_max_mpu_wakeup_lat(dev, t); }
static int imx072_sensor_power_set(struct v4l2_int_device *s, enum v4l2_power power) { struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); struct isp_csi2_lanes_cfg lanecfg; struct isp_csi2_phy_cfg phyconfig; static enum v4l2_power previous_power = V4L2_POWER_OFF; // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [START] static struct pm_qos_request_list *qos_request; // 20110426 [email protected] Update omap_pm_set_max_mpu_wakeup_lat() for 2.6.35 kernel [END] int err = 0; switch (power) { case V4L2_POWER_ON: /* Power Up Sequence */ printk(KERN_DEBUG "imx072_sensor_power_set(ON)\n"); // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [START] #if 1 /* * Through-put requirement: * Set max OCP freq for 3630 is 200 MHz through-put * is in KByte/s so 200000 KHz * 4 = 800000 KByte/s */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 800000); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(&qos_request, 12); #endif // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [END] isp_csi2_reset(&isp->isp_csi2); lanecfg.clk.pol = IMX072_CSI2_CLOCK_POLARITY; lanecfg.clk.pos = IMX072_CSI2_CLOCK_LANE; lanecfg.data[0].pol = IMX072_CSI2_DATA0_POLARITY; lanecfg.data[0].pos = IMX072_CSI2_DATA0_LANE; lanecfg.data[1].pol = IMX072_CSI2_DATA1_POLARITY; lanecfg.data[1].pos = IMX072_CSI2_DATA1_LANE; lanecfg.data[2].pol = 0; lanecfg.data[2].pos = 0; lanecfg.data[3].pol = 0; lanecfg.data[3].pos = 0; isp_csi2_complexio_lanes_config(&isp->isp_csi2, &lanecfg); isp_csi2_complexio_lanes_update(&isp->isp_csi2, true); isp_csi2_ctrl_config_ecc_enable(&isp->isp_csi2, true); phyconfig.ths_term = IMX072_CSI2_PHY_THS_TERM; phyconfig.ths_settle = IMX072_CSI2_PHY_THS_SETTLE; phyconfig.tclk_term = IMX072_CSI2_PHY_TCLK_TERM; phyconfig.tclk_miss = IMX072_CSI2_PHY_TCLK_MISS; phyconfig.tclk_settle = IMX072_CSI2_PHY_TCLK_SETTLE; isp_csi2_phy_config(&isp->isp_csi2, &phyconfig); isp_csi2_phy_update(&isp->isp_csi2, true); isp_configure_interface(vdev->cam->isp, &imx072_if_config); //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] [2011.09.19] - CAM gpio_direction_output(SUBPM_ENABLE, 1); //--]] LGE_UBIQUIX_MODIFIED_END : [email protected] [2011.09.19] - CAM /* Request and configure gpio pins */ if (gpio_request(IMX072_RESET_GPIO, "imx072_rst") != 0) return -EIO; subpm_set_output(SWREG,1); subpm_output_enable(); subpm_set_output(LDO4,1); subpm_output_enable(); subpm_set_output(LDO3,1); subpm_output_enable(); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_1_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); udelay(100); /* have to put sensor to reset to guarantee detection */ gpio_direction_output(IMX072_RESET_GPIO, 1); // gpio_set_value(IMX072_RESET_GPIO, 1); udelay(100); // gpio_direction_output(IMX072_RESET_GPIO, 0); gpio_set_value(IMX072_RESET_GPIO, 0); udelay(1500); /* nRESET is active LOW. set HIGH to release reset */ // gpio_direction_output(IMX072_RESET_GPIO, 1); gpio_set_value(IMX072_RESET_GPIO, 1); udelay(300); break; case V4L2_POWER_OFF: subpm_set_output(LDO5,0); subpm_output_enable(); gpio_set_value(DW9716_VCM_ENABLE, 0); isp_disable_mclk(isp); isp_csi2_complexio_power(&isp->isp_csi2, ISP_CSI2_POWER_OFF); isp_csi2_reset(&isp->isp_csi2); isp_csi2_ctrl_config_ecc_enable(&isp->isp_csi2, true); isp_csi2_complexio_power(&isp->isp_csi2, ISP_CSI2_POWER_OFF); isp_disable_mclk(isp); //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] [2011.09.19] - CAM gpio_direction_output(SUBPM_ENABLE, 0); //--]] LGE_UBIQUIX_MODIFIED_END : [email protected] [2011.09.19] - CAM break; case V4L2_POWER_STANDBY: printk(KERN_DEBUG "imx072_sensor_power_set(%s)\n", (power == V4L2_POWER_OFF) ? "OFF" : "STANDBY"); /* Power Down Sequence */ isp_csi2_complexio_power(&isp->isp_csi2, ISP_CSI2_POWER_OFF); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); gpio_set_value(IMX072_RESET_GPIO, 0); udelay(5); subpm_set_output(LDO3,0); subpm_output_enable(); subpm_set_output(LDO4,0); subpm_output_enable(); subpm_set_output(SWREG,0); subpm_output_enable(); gpio_free(IMX072_RESET_GPIO); // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [START] #if 1 /* Remove pm constraints */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0); //omap_pm_set_max_mpu_wakeup_lat(vdev->cam->isp, -1); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); #endif // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [END] /* Make sure not to disable the MCLK twice in a row */ if (previous_power == V4L2_POWER_ON) isp_disable_mclk(isp); //--[[ LGE_UBIQUIX_MODIFIED_START : [email protected] [2011.09.19] - CAM isp_disable_mclk(isp); //--]] LGE_UBIQUIX_MODIFIED_END : [email protected] [2011.09.19] - CAM break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return err; }
static int yacd5b1s_sensor_power_set(struct v4l2_int_device *dev, enum v4l2_power power) { struct omap34xxcam_videodev *vdev = dev->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); static enum v4l2_power previous_power = V4L2_POWER_OFF; static struct pm_qos_request_list *qos_request_sec; /* 20110527 [email protected] camera l3 clock*/ int err = 0; switch (power) { case V4L2_POWER_ON: /* Power Up Sequence */ printk(KERN_DEBUG "yacd5b1s_sensor_power_set(ON)\n"); // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [START] #if 1 omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 800000); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(&qos_request_sec, 12); /* 20110527 [email protected] camera l3 clock*/ #endif // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [END] isp_configure_interface(vdev->cam->isp,&yacd5b1s_if_config); if (gpio_request(YACD5B1S_RESET_GPIO, "yacd5b1s_rst") != 0) printk("\n\n\n>>>>>>>>>>>>YACD5B1S_RESET_GPIO_gpio_request_error\n\n\n");//return -EIO; if (gpio_request(YACD5B1S_STANDBY_GPIO, "yacd5b1s_PWD") != 0) printk("\n\n\n>>>>>>>>>>>>YACD5B1S_STANDBY_GPIO_gpio_request_error\n\n\n");//return -EIO;return -EIO; #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, SET_VMMC1_V2_8,VMMC1_DEDICATED ); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VMMC1_DEV_GRP_P1,VMMC1_DEV_GRP ); #endif udelay(20); #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX3_1_8_V, TWL4030_VAUX3_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX3_DEV_GRP); #endif twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_1_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); //wait typical 500ms for xclk to settle //mdelay(500); gpio_direction_output(YACD5B1S_STANDBY_GPIO, true); udelay(100); gpio_set_value(YACD5B1S_STANDBY_GPIO, 0); udelay(1500); gpio_set_value(YACD5B1S_STANDBY_GPIO, 1); mdelay(100); udelay(50); gpio_direction_output(YACD5B1S_RESET_GPIO, true); udelay(100); gpio_set_value(YACD5B1S_RESET_GPIO, 0); /* set to output mode */ udelay(1500); gpio_set_value(YACD5B1S_RESET_GPIO, 1); udelay(300); break; case V4L2_POWER_OFF: printk(KERN_DEBUG "yacd5b1s_sensor_power_set(OFF)\n"); /* Power Down Sequence */ gpio_set_value(YACD5B1S_RESET_GPIO, 0); udelay(50); gpio_set_value(YACD5B1S_STANDBY_GPIO, 0); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE,VMMC1_DEV_GRP ); #endif #if 1 twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX3_DEV_GRP); #endif gpio_free(YACD5B1S_STANDBY_GPIO); gpio_free(YACD5B1S_RESET_GPIO); // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [START] #if 1 omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(&qos_request_sec, -1); #endif // [email protected] [TBD]Temporarily block the following code because PM APIs have been changed [END] break; case V4L2_POWER_STANDBY: printk(KERN_DEBUG "yacd5b1s_sensor_power_set(STANDBY)\n"); gpio_set_value(YACD5B1S_RESET_GPIO, 0); udelay(50); gpio_set_value(YACD5B1S_STANDBY_GPIO, 0); udelay(50); gpio_free(YACD5B1S_STANDBY_GPIO); gpio_free(YACD5B1S_RESET_GPIO); break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return err; }
static void rm680_bt_set_pm_limits(struct device *dev, bool set) { omap_pm_set_max_mpu_wakeup_lat(dev, set ? H4P_WAKEUP_LATENCY : -1); }
static int hi253_power_set(struct v4l2_int_device *s, enum v4l2_power power,u8 type) { struct omap34xxcam_videodev *vdev = s->u.slave->master->priv; struct isp_device *isp = dev_get_drvdata(vdev->cam->isp); static enum v4l2_power previous_power = V4L2_POWER_OFF; static struct pm_qos_request_list *qos_request; int err = 0; printk(KERN_ERR "previous_power = %d,Hi253_sensor_power_set(%d)\n",previous_power,power); switch (power) { case V4L2_POWER_ON: /* * Through-put requirement: * Set max OCP freq for 3630 is 200 MHz through-put * is in KByte/s so 200000 KHz * 4 = 800000 KByte/s */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 800000); /* Hold a constraint to keep MPU in C1 */ omap_pm_set_max_mpu_wakeup_lat(&qos_request, 12); isp_configure_interface(vdev->cam->isp,&Hi253_if_config); gpio_direction_output(BF3703_STANDBY_GPIO,1); gpio_direction_output(HI253_STANDBY_GPIO, 0); udelay(10); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_2_8_V, TWL4030_VAUX4_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_P1, TWL4030_VAUX4_DEV_GRP); udelay(100); printk(KERN_ERR "VAUX4 = 2.8V\n"); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VMMC2_1_5_V, TWL4030_VMMC2_DEDICATED); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VMMC2_DEV_GRP_P1, TWL4030_VMMC2_DEV_GRP); udelay(100); printk(KERN_ERR "VMMC2 = 1.5V\n"); gpio_direction_output(HI253_RESET_GPIO, 1); mdelay(1); /* have to put sensor to reset to guarantee detection */ gpio_direction_output(HI253_RESET_GPIO, 0); udelay(1500); /* nRESET is active LOW. set HIGH to release reset */ gpio_direction_output(HI253_RESET_GPIO, 1); printk(KERN_ERR "reset camera(HI253)\n"); break; case V4L2_POWER_OFF: case V4L2_POWER_STANDBY: printk(KERN_ERR "_sensor_power_set(OFF )\n"); gpio_direction_output(HI253_STANDBY_GPIO, 1); printk(KERN_DEBUG "hi253_sensor_power_set(STANDBY)\n"); /* Remove pm constraints */ omap_pm_set_min_bus_tput(vdev->cam->isp, OCP_INITIATOR_AGENT, 0); omap_pm_set_max_mpu_wakeup_lat(&qos_request, -1); /* twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VAUX4_DEV_GRP); twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, VAUX_DEV_GRP_NONE, TWL4030_VMMC2_DEV_GRP); */ /* Make sure not to disable the MCLK twice in a row */ if (previous_power == V4L2_POWER_ON){ isp_disable_mclk(isp); } break; // printk(KERN_ERR "_sensor_power_set(STANDBY)\n"); break; } /* Save powerstate to know what was before calling POWER_ON. */ previous_power = power; return err; }