static int mxs_saif_set_clk(struct mxs_saif *saif, unsigned int mclk, unsigned int rate) { u32 scr; int ret; struct mxs_saif *master_saif; dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate); /* */ master_saif = mxs_saif_get_master(saif); if (!master_saif) return -EINVAL; dev_dbg(saif->dev, "master saif%d\n", master_saif->id); /* */ if (master_saif->ongoing && rate != master_saif->cur_rate) { dev_err(saif->dev, "can not change clock, master saif%d(rate %d) is ongoing\n", master_saif->id, master_saif->cur_rate); return -EINVAL; } scr = __raw_readl(master_saif->base + SAIF_CTRL); scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE; scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; /* */ clk_prepare_enable(master_saif->clk); if (master_saif->mclk_in_use) { if (mclk % 32 == 0) { scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; ret = clk_set_rate(master_saif->clk, 512 * rate); } else if (mclk % 48 == 0) { scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE; ret = clk_set_rate(master_saif->clk, 384 * rate); } else { /* */ clk_disable_unprepare(master_saif->clk); return -EINVAL; } } else { ret = clk_set_rate(master_saif->clk, 512 * rate); scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; } clk_disable_unprepare(master_saif->clk); if (ret) return ret; master_saif->cur_rate = rate; if (!master_saif->mclk_in_use) { __raw_writel(scr, master_saif->base + SAIF_CTRL); return 0; } /* */ switch (mclk / rate) { case 32: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4); break; case 64: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3); break; case 128: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2); break; case 256: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1); break; case 512: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0); break; case 48: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3); break; case 96: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2); break; case 192: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1); break; case 384: scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0); break; default: return -EINVAL; } __raw_writel(scr, master_saif->base + SAIF_CTRL); return 0; }
static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev) { struct atmel_ac97c *chip = (struct atmel_ac97c *)dev; irqreturn_t retval = IRQ_NONE; u32 sr = ac97c_readl(chip, SR); u32 casr = ac97c_readl(chip, CASR); u32 cosr = ac97c_readl(chip, COSR); u32 camr = ac97c_readl(chip, CAMR); if (sr & AC97C_SR_CAEVT) { struct snd_pcm_runtime *runtime; int offset, next_period, block_size; dev_dbg(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n", casr & AC97C_CSR_OVRUN ? " OVRUN" : "", casr & AC97C_CSR_RXRDY ? " RXRDY" : "", casr & AC97C_CSR_UNRUN ? " UNRUN" : "", casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", casr & AC97C_CSR_TXRDY ? " TXRDY" : "", !casr ? " NONE" : ""); if (!cpu_is_at32ap7000()) { if ((casr & camr) & AC97C_CSR_ENDTX) { runtime = chip->playback_substream->runtime; block_size = frames_to_bytes(runtime, runtime->period_size); chip->playback_period++; if (chip->playback_period == runtime->periods) chip->playback_period = 0; next_period = chip->playback_period + 1; if (next_period == runtime->periods) next_period = 0; offset = block_size * next_period; writel(runtime->dma_addr + offset, chip->regs + ATMEL_PDC_TNPR); writel(block_size / 2, chip->regs + ATMEL_PDC_TNCR); snd_pcm_period_elapsed( chip->playback_substream); } if ((casr & camr) & AC97C_CSR_ENDRX) { runtime = chip->capture_substream->runtime; block_size = frames_to_bytes(runtime, runtime->period_size); chip->capture_period++; if (chip->capture_period == runtime->periods) chip->capture_period = 0; next_period = chip->capture_period + 1; if (next_period == runtime->periods) next_period = 0; offset = block_size * next_period; writel(runtime->dma_addr + offset, chip->regs + ATMEL_PDC_RNPR); writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); snd_pcm_period_elapsed(chip->capture_substream); } } retval = IRQ_HANDLED; } if (sr & AC97C_SR_COEVT) { dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n", cosr & AC97C_CSR_OVRUN ? " OVRUN" : "", cosr & AC97C_CSR_RXRDY ? " RXRDY" : "", cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "", cosr & AC97C_CSR_TXRDY ? " TXRDY" : "", !cosr ? " NONE" : ""); retval = IRQ_HANDLED; } if (retval == IRQ_NONE) { dev_err(&chip->pdev->dev, "spurious interrupt sr 0x%08x " "casr 0x%08x cosr 0x%08x\n", sr, casr, cosr); } return retval; }
/* size of returned buffer is part of USB spec */ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); int status, lstatus, retval = 0, len = 0; unsigned int port = wIndex - 1; unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * port; u16 wPortChange, wPortStatus; unsigned long flags; if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) return -ETIMEDOUT; spin_lock_irqsave(&uhci->lock, flags); switch (typeReq) { case GetHubStatus: *(__le32 *)buf = cpu_to_le32(0); OK(4); /* hub power */ case GetPortStatus: if (port >= uhci->rh_numports) goto err; uhci_check_ports(uhci); status = inw(port_addr); /* Intel controllers report the OverCurrent bit active on. * VIA controllers report it active off, so we'll adjust the * bit value. (It's not standardized in the UHCI spec.) */ if (to_pci_dev(hcd->self.controller)->vendor == PCI_VENDOR_ID_VIA) status ^= USBPORTSC_OC; /* UHCI doesn't support C_RESET (always false) */ wPortChange = lstatus = 0; if (status & USBPORTSC_CSC) wPortChange |= USB_PORT_STAT_C_CONNECTION; if (status & USBPORTSC_PEC) wPortChange |= USB_PORT_STAT_C_ENABLE; if ((status & USBPORTSC_OCC) && !ignore_oc) wPortChange |= USB_PORT_STAT_C_OVERCURRENT; if (test_bit(port, &uhci->port_c_suspend)) { wPortChange |= USB_PORT_STAT_C_SUSPEND; lstatus |= 1; } if (test_bit(port, &uhci->resuming_ports)) lstatus |= 4; /* UHCI has no power switching (always on) */ wPortStatus = USB_PORT_STAT_POWER; if (status & USBPORTSC_CCS) wPortStatus |= USB_PORT_STAT_CONNECTION; if (status & USBPORTSC_PE) { wPortStatus |= USB_PORT_STAT_ENABLE; if (status & SUSPEND_BITS) wPortStatus |= USB_PORT_STAT_SUSPEND; } if (status & USBPORTSC_OC) wPortStatus |= USB_PORT_STAT_OVERCURRENT; if (status & USBPORTSC_PR) wPortStatus |= USB_PORT_STAT_RESET; if (status & USBPORTSC_LSDA) wPortStatus |= USB_PORT_STAT_LOW_SPEED; if (wPortChange) dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n", wIndex, status, lstatus); *(__le16 *)buf = cpu_to_le16(wPortStatus); *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange); OK(4); case SetHubFeature: /* We don't implement these */ case ClearHubFeature: switch (wValue) { case C_HUB_OVER_CURRENT: case C_HUB_LOCAL_POWER: OK(0); default: goto err; } break; case SetPortFeature: if (port >= uhci->rh_numports) goto err; switch (wValue) { case USB_PORT_FEAT_SUSPEND: SET_RH_PORTSTAT(USBPORTSC_SUSP); OK(0); case USB_PORT_FEAT_RESET: SET_RH_PORTSTAT(USBPORTSC_PR); /* Reset terminates Resume signalling */ uhci_finish_suspend(uhci, port, port_addr); /* USB v2.0 7.1.7.5 */ uhci->ports_timeout = jiffies + msecs_to_jiffies(50); OK(0); case USB_PORT_FEAT_POWER: /* UHCI has no power switching */ OK(0); default: goto err; } break; case ClearPortFeature: if (port >= uhci->rh_numports) goto err; switch (wValue) { case USB_PORT_FEAT_ENABLE: CLR_RH_PORTSTAT(USBPORTSC_PE); /* Disable terminates Resume signalling */ uhci_finish_suspend(uhci, port, port_addr); OK(0); case USB_PORT_FEAT_C_ENABLE: CLR_RH_PORTSTAT(USBPORTSC_PEC); OK(0); case USB_PORT_FEAT_SUSPEND: if (!(inw(port_addr) & USBPORTSC_SUSP)) { /* Make certain the port isn't suspended */ uhci_finish_suspend(uhci, port, port_addr); } else if (!test_and_set_bit(port, &uhci->resuming_ports)) { SET_RH_PORTSTAT(USBPORTSC_RD); /* The controller won't allow RD to be set * if the port is disabled. When this happens * just skip the Resume signalling. */ if (!(inw(port_addr) & USBPORTSC_RD)) uhci_finish_suspend(uhci, port, port_addr); else /* USB v2.0 7.1.7.7 */ uhci->ports_timeout = jiffies + msecs_to_jiffies(20); } OK(0); case USB_PORT_FEAT_C_SUSPEND: clear_bit(port, &uhci->port_c_suspend); OK(0); case USB_PORT_FEAT_POWER: /* UHCI has no power switching */ goto err; case USB_PORT_FEAT_C_CONNECTION: CLR_RH_PORTSTAT(USBPORTSC_CSC); OK(0); case USB_PORT_FEAT_C_OVER_CURRENT: CLR_RH_PORTSTAT(USBPORTSC_OCC); OK(0); case USB_PORT_FEAT_C_RESET: /* this driver won't report these */ OK(0); default: goto err; } break; case GetHubDescriptor: len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); memcpy(buf, root_hub_hub_des, len); if (len > 2) buf[2] = uhci->rh_numports; OK(len); default: err: retval = -EPIPE; } spin_unlock_irqrestore(&uhci->lock, flags); return retval; }
static int sis630_block_data(struct i2c_adapter *adap, union i2c_smbus_data *data, int read_write) { int i, len = 0, rc = 0; u8 oldclock = 0; if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; if (len < 0) len = 0; else if (len > 32) len = 32; sis630_write(SMB_COUNT, len); for (i=1; i <= len; i++) { dev_dbg(&adap->dev, "set data 0x%02x\n", data->block[i]); /* set data */ sis630_write(SMB_BYTE+(i-1)%8, data->block[i]); if (i==8 || (len<8 && i==len)) { dev_dbg(&adap->dev, "start trans len=%d i=%d\n",len ,i); /* first transaction */ if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) return -1; } else if ((i-1)%8 == 7 || i==len) { dev_dbg(&adap->dev, "trans_wait len=%d i=%d\n",len,i); if (i>8) { dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i); /* If this is not first transaction, we must clear sticky bit. clear SMBARY_STS */ sis630_write(SMB_STS,0x10); } if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { dev_dbg(&adap->dev, "trans_wait failed\n"); rc = -1; break; } } } } else { /* read request */ data->block[0] = len = 0; if (sis630_transaction_start(adap, SIS630_BLOCK_DATA, &oldclock)) { return -1; } do { if (sis630_transaction_wait(adap, SIS630_BLOCK_DATA)) { dev_dbg(&adap->dev, "trans_wait failed\n"); rc = -1; break; } /* if this first transaction then read byte count */ if (len == 0) data->block[0] = sis630_read(SMB_COUNT); /* just to be sure */ if (data->block[0] > 32) data->block[0] = 32; dev_dbg(&adap->dev, "block data read len=0x%x\n", data->block[0]); for (i=0; i < 8 && len < data->block[0]; i++,len++) { dev_dbg(&adap->dev, "read i=%d len=%d\n", i, len); data->block[len+1] = sis630_read(SMB_BYTE+i); } dev_dbg(&adap->dev, "clear smbary_sts len=%d i=%d\n",len,i); /* clear SMBARY_STS */ sis630_write(SMB_STS,0x10); } while(len < data->block[0]); } sis630_transaction_end(adap, oldclock); return rc; }
static int ltr558_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; struct ltr558_chip *chip; struct iio_dev *indio_dev; /* data memory allocation */ indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { dev_err(&client->dev, "iio allocation fails\n"); ret = -ENOMEM; goto exit; } chip = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); chip->client = client; chip->irq = client->irq; if (chip->irq > 0) { ret = request_threaded_irq(chip->irq, NULL, threshold_isr, IRQF_SHARED, "LTR558_ALS", chip); if (ret) { dev_err(&client->dev, "Unable to register irq %d; " "ret %d\n", chip->irq, ret); goto exit_iio_free; } } mutex_init(&chip->lock); ret = ltr558_chip_init(client); if (ret) goto exit_irq; indio_dev->info = <r558_info; indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; ret = iio_device_register(indio_dev); if (ret) { dev_err(&client->dev, "iio registration fails\n"); goto exit_irq; } chip->supply[VDD] = regulator_get(&client->dev, "vdd"); if (IS_ERR(chip->supply[VDD])) { dev_err(&client->dev, "could not get vdd regulator\n"); ret = PTR_ERR(chip->supply[VDD]); goto exit_irq; } chip->supply[LED] = regulator_get(&client->dev, "vled"); if (IS_ERR(chip->supply[LED])) { dev_err(&client->dev, "could not get vled regulator\n"); ret = PTR_ERR(chip->supply[LED]); goto exit_irq; } ret = regulator_enable(chip->supply[VDD]); if (ret) { dev_err(&client->dev, "func:%s regulator enable failed\n", __func__); goto exit_irq; } ret = i2c_smbus_read_byte_data(client, LTR558_MANUFACTURER_ID); if (ret < 0) { dev_err(&client->dev, "Err in reading register %d, error %d\n", LTR558_MANUFACTURER_ID, ret); goto exit_irq; } if (ret != LTR_MANUFACTURER_ID) { dev_err(&client->dev, "sensor not found\n"); goto exit_irq; } ret = regulator_disable(chip->supply[VDD]); if (ret) { dev_err(&client->dev, "func:%s regulator disable failed\n", __func__); goto exit_irq; } dev_dbg(&client->dev, "%s() success\n", __func__); return 0; exit_irq: if (chip->irq > 0) free_irq(chip->irq, chip); exit_iio_free: iio_device_free(indio_dev); exit: return ret; }
static int marimba_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct marimba_platform_data *pdata = client->dev.platform_data; struct i2c_adapter *ssbi_adap; struct marimba *marimba; int i, status, rc, client_loop, adie_slave_idx_offset; int rc_bahama = 0, rc_marimba = 0; if (!pdata) { dev_dbg(&client->dev, "no platform data?\n"); return -EINVAL; } if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { dev_dbg(&client->dev, "can't talk I2C?\n"); return -EIO; } /* First, identify the codec type */ if (pdata->marimba_setup != NULL) { rc_marimba = pdata->marimba_setup(); if (rc_marimba) pdata->marimba_shutdown(); } if (pdata->bahama_setup != NULL && cur_connv_type != BAHAMA_ID) { rc_bahama = pdata->bahama_setup(); if (rc_bahama) pdata->bahama_shutdown(cur_connv_type); } if (rc_marimba & rc_bahama) return -EAGAIN; marimba = &marimba_modules[ADIE_ARRY_SIZE - 1]; marimba->client = client; mutex_init(&marimba->xfer_lock); rc = get_adie_type(); mutex_destroy(&marimba->xfer_lock); if (rc < 0) { if (pdata->bahama_setup != NULL) pdata->bahama_shutdown(cur_adie_type); if (pdata->marimba_shutdown != NULL) pdata->marimba_shutdown(); return -ENODEV; } if (rc < 2) { adie_arry_idx = 0; adie_slave_idx_offset = 0; client_loop = 0; cur_codec_type = rc; if (cur_connv_type < 0) cur_connv_type = rc; if (pdata->bahama_shutdown != NULL) pdata->bahama_shutdown(cur_connv_type); } else { adie_arry_idx = 5; adie_slave_idx_offset = 5; client_loop = 1; cur_connv_type = rc; } marimba = &marimba_modules[adie_arry_idx]; marimba->client = client; mutex_init(&marimba->xfer_lock); for (i = 1; i <= (NUM_ADD - client_loop); i++) { /* Skip adding BT/FM for Timpani */ if (i == 1 && rc >= 1) i++; marimba = &marimba_modules[i + adie_arry_idx]; if (i != MARIMBA_ID_TSADC) marimba->client = i2c_new_dummy(client->adapter, pdata->slave_id[i + adie_slave_idx_offset]); else { ssbi_adap = i2c_get_adapter(MARIMBA_SSBI_ADAP); marimba->client = i2c_new_dummy(ssbi_adap, 0x55); } if (!marimba->client) { dev_err(&marimba->client->dev, "can't attach client %d\n", i); status = -ENOMEM; goto fail; } strlcpy(marimba->client->name, id->name, sizeof(marimba->client->name)); mutex_init(&marimba->xfer_lock); } marimba_init_reg(client, id->driver_data); status = marimba_add_child(pdata, id->driver_data); marimba_pdata = pdata; return 0; fail: return status; }
static int synquacer_i2c_probe(struct platform_device *pdev) { struct synquacer_i2c *i2c; struct resource *r; u32 bus_speed; int ret; i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); if (!i2c) return -ENOMEM; bus_speed = i2c_acpi_find_bus_speed(&pdev->dev); if (!bus_speed) device_property_read_u32(&pdev->dev, "clock-frequency", &bus_speed); device_property_read_u32(&pdev->dev, "socionext,pclk-rate", &i2c->pclkrate); i2c->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(i2c->pclk) && PTR_ERR(i2c->pclk) == -EPROBE_DEFER) return -EPROBE_DEFER; if (!IS_ERR_OR_NULL(i2c->pclk)) { dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk); ret = clk_prepare_enable(i2c->pclk); if (ret) { dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret); return ret; } i2c->pclkrate = clk_get_rate(i2c->pclk); } if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE || i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE) { dev_err(&pdev->dev, "PCLK missing or out of range (%d)\n", i2c->pclkrate); return -EINVAL; } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); i2c->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(i2c->base)) return PTR_ERR(i2c->base); i2c->irq = platform_get_irq(pdev, 0); if (i2c->irq < 0) { dev_err(&pdev->dev, "no IRQ resource found\n"); return -ENODEV; } ret = devm_request_irq(&pdev->dev, i2c->irq, synquacer_i2c_isr, 0, dev_name(&pdev->dev), i2c); if (ret < 0) { dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq); return ret; } i2c->state = STATE_IDLE; i2c->dev = &pdev->dev; i2c->adapter = synquacer_i2c_ops; i2c_set_adapdata(&i2c->adapter, i2c); i2c->adapter.dev.parent = &pdev->dev; i2c->adapter.nr = pdev->id; init_completion(&i2c->completion); if (bus_speed < 400000) i2c->speed_khz = SYNQUACER_I2C_SPEED_SM; else i2c->speed_khz = SYNQUACER_I2C_SPEED_FM; synquacer_i2c_hw_init(i2c); ret = i2c_add_numbered_adapter(&i2c->adapter); if (ret) { dev_err(&pdev->dev, "failed to add bus to i2c core\n"); return ret; } platform_set_drvdata(pdev, i2c); dev_info(&pdev->dev, "%s: synquacer_i2c adapter\n", dev_name(&i2c->adapter.dev)); return 0; }
static void axp288_charger_extcon_evt_worker(struct work_struct *work) { struct axp288_chrg_info *info = container_of(work, struct axp288_chrg_info, cable.work); int ret, current_limit; bool changed = false; struct extcon_dev *edev = info->cable.edev; bool old_connected = info->cable.connected; /* Determine cable/charger type */ if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_SDP) > 0) { dev_dbg(&info->pdev->dev, "USB SDP charger is connected"); info->cable.connected = true; info->cable.chg_type = POWER_SUPPLY_TYPE_USB; } else if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_CDP) > 0) { dev_dbg(&info->pdev->dev, "USB CDP charger is connected"); info->cable.connected = true; info->cable.chg_type = POWER_SUPPLY_TYPE_USB_CDP; } else if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_DCP) > 0) { dev_dbg(&info->pdev->dev, "USB DCP charger is connected"); info->cable.connected = true; info->cable.chg_type = POWER_SUPPLY_TYPE_USB_DCP; } else { if (old_connected) dev_dbg(&info->pdev->dev, "USB charger disconnected"); info->cable.connected = false; info->cable.chg_type = POWER_SUPPLY_TYPE_USB; } /* Cable status changed */ if (old_connected != info->cable.connected) changed = true; if (!changed) return; mutex_lock(&info->lock); if (info->is_charger_enabled && !info->cable.connected) { info->enable_charger = false; ret = axp288_charger_enable_charger(info, info->enable_charger); if (ret < 0) dev_err(&info->pdev->dev, "cannot disable charger (%d)", ret); } else if (!info->is_charger_enabled && info->cable.connected) { switch (info->cable.chg_type) { case POWER_SUPPLY_TYPE_USB: current_limit = ILIM_500MA; break; case POWER_SUPPLY_TYPE_USB_CDP: current_limit = ILIM_1500MA; break; case POWER_SUPPLY_TYPE_USB_DCP: current_limit = ILIM_2000MA; break; default: /* Unknown */ current_limit = 0; break; } /* Set vbus current limit first, then enable charger */ ret = axp288_charger_set_vbus_inlmt(info, current_limit); if (ret < 0) { dev_err(&info->pdev->dev, "error setting current limit (%d)", ret); } else { info->enable_charger = (current_limit > 0); ret = axp288_charger_enable_charger(info, info->enable_charger); if (ret < 0) dev_err(&info->pdev->dev, "cannot enable charger (%d)", ret); } } if (changed) info->health = axp288_get_charger_health(info); mutex_unlock(&info->lock); if (changed) power_supply_changed(info->psy_usb); }
static int axp288_charger_probe(struct platform_device *pdev) { int ret, i, pirq; struct axp288_chrg_info *info; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct power_supply_config charger_cfg = {}; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; info->pdev = pdev; info->regmap = axp20x->regmap; info->regmap_irqc = axp20x->regmap_irqc; info->pdata = pdev->dev.platform_data; if (!info->pdata) { /* Try ACPI provided pdata via device properties */ if (!device_property_present(&pdev->dev, "axp288_charger_data\n")) dev_err(&pdev->dev, "failed to get platform data\n"); return -ENODEV; } info->cable.edev = extcon_get_extcon_dev(AXP288_EXTCON_DEV_NAME); if (info->cable.edev == NULL) { dev_dbg(&pdev->dev, "%s is not ready, probe deferred\n", AXP288_EXTCON_DEV_NAME); return -EPROBE_DEFER; } /* Register for extcon notification */ INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker); info->cable.nb.notifier_call = axp288_charger_handle_cable_evt; ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); if (ret) { dev_err(&info->pdev->dev, "failed to register extcon notifier for SDP %d\n", ret); return ret; } ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); if (ret) { dev_err(&info->pdev->dev, "failed to register extcon notifier for CDP %d\n", ret); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); return ret; } ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, &info->cable.nb); if (ret) { dev_err(&info->pdev->dev, "failed to register extcon notifier for DCP %d\n", ret); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); return ret; } platform_set_drvdata(pdev, info); mutex_init(&info->lock); /* Register with power supply class */ charger_cfg.drv_data = info; info->psy_usb = power_supply_register(&pdev->dev, &axp288_charger_desc, &charger_cfg); if (IS_ERR(info->psy_usb)) { dev_err(&pdev->dev, "failed to register power supply charger\n"); ret = PTR_ERR(info->psy_usb); goto psy_reg_failed; } /* Register for OTG notification */ INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker); info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt; ret = extcon_register_notifier(info->otg.cable, EXTCON_USB_HOST, &info->otg.id_nb); if (ret) dev_warn(&pdev->dev, "failed to register otg notifier\n"); if (info->otg.cable) info->otg.id_short = extcon_get_cable_state_( info->otg.cable, EXTCON_USB_HOST); /* Register charger interrupts */ for (i = 0; i < CHRG_INTR_END; i++) { pirq = platform_get_irq(info->pdev, i); info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); if (info->irq[i] < 0) { dev_warn(&info->pdev->dev, "failed to get virtual interrupt=%d\n", pirq); ret = info->irq[i]; goto intr_reg_failed; } ret = devm_request_threaded_irq(&info->pdev->dev, info->irq[i], NULL, axp288_charger_irq_thread_handler, IRQF_ONESHOT, info->pdev->name, info); if (ret) { dev_err(&pdev->dev, "failed to request interrupt=%d\n", info->irq[i]); goto intr_reg_failed; } } charger_init_hw_regs(info); return 0; intr_reg_failed: if (info->otg.cable) extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST, &info->otg.id_nb); power_supply_unregister(info->psy_usb); psy_reg_failed: extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP, &info->cable.nb); extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP, &info->cable.nb); return ret; }
static int diagfwd_runtime_resume(struct device *dev) { dev_dbg(dev, "pm_runtime: resuming...\n"); return 0; }
static int __init davinci_vc_probe(struct platform_device *pdev) { struct davinci_vc *davinci_vc; struct resource *res, *mem; struct mfd_cell *cell = NULL; int ret; davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL); if (!davinci_vc) { dev_dbg(&pdev->dev, "could not allocate memory for private data\n"); return -ENOMEM; } davinci_vc->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(davinci_vc->clk)) { dev_dbg(&pdev->dev, "could not get the clock for voice codec\n"); ret = -ENODEV; goto fail1; } clk_enable(davinci_vc->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no mem resource\n"); ret = -ENODEV; goto fail2; } davinci_vc->pbase = res->start; davinci_vc->base_size = resource_size(res); mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size, pdev->name); if (!mem) { dev_err(&pdev->dev, "VCIF region already claimed\n"); ret = -EBUSY; goto fail2; } davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size); if (!davinci_vc->base) { dev_err(&pdev->dev, "can't ioremap mem resource.\n"); ret = -ENOMEM; goto fail3; } res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENXIO; goto fail4; } davinci_vc->davinci_vcif.dma_tx_channel = res->start; davinci_vc->davinci_vcif.dma_tx_addr = (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENXIO; goto fail4; } davinci_vc->davinci_vcif.dma_rx_channel = res->start; davinci_vc->davinci_vcif.dma_rx_addr = (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); davinci_vc->dev = &pdev->dev; davinci_vc->pdev = pdev; /* Voice codec interface client */ cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; cell->name = "davinci-vcif"; cell->mfd_data = davinci_vc; /* Voice codec CQ93VC client */ cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; cell->name = "cq93vc-codec"; cell->mfd_data = davinci_vc; ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, DAVINCI_VC_CELLS, NULL, 0); if (ret != 0) { dev_err(&pdev->dev, "fail to register client devices\n"); goto fail4; } return 0; fail4: iounmap(davinci_vc->base); fail3: release_mem_region(davinci_vc->pbase, davinci_vc->base_size); fail2: clk_disable(davinci_vc->clk); clk_put(davinci_vc->clk); davinci_vc->clk = NULL; fail1: kfree(davinci_vc); return ret; }
static int diagfwd_runtime_suspend(struct device *dev) { dev_dbg(dev, "pm_runtime: suspending...\n"); return 0; }
/** * mei_reset - resets host and fw. * * @dev: the device structure * * Return: 0 on success or < 0 if the reset hasn't succeeded */ int mei_reset(struct mei_device *dev) { enum mei_dev_state state = dev->dev_state; bool interrupts_enabled; int ret; if (state != MEI_DEV_INITIALIZING && state != MEI_DEV_DISABLED && state != MEI_DEV_POWER_DOWN && state != MEI_DEV_POWER_UP) { char fw_sts_str[MEI_FW_STATUS_STR_SZ]; mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ); dev_warn(dev->dev, "unexpected reset: dev_state = %s fw status = %s\n", mei_dev_state_str(state), fw_sts_str); } mei_clear_interrupts(dev); /* we're already in reset, cancel the init timer * if the reset was called due the hbm protocol error * we need to call it before hw start * so the hbm watchdog won't kick in */ mei_hbm_idle(dev); /* enter reset flow */ interrupts_enabled = state != MEI_DEV_POWER_DOWN; dev->dev_state = MEI_DEV_RESETTING; dev->reset_count++; if (dev->reset_count > MEI_MAX_CONSEC_RESET) { dev_err(dev->dev, "reset: reached maximal consecutive resets: disabling the device\n"); dev->dev_state = MEI_DEV_DISABLED; return -ENODEV; } ret = mei_hw_reset(dev, interrupts_enabled); /* fall through and remove the sw state even if hw reset has failed */ /* no need to clean up software state in case of power up */ if (state != MEI_DEV_INITIALIZING && state != MEI_DEV_POWER_UP) mei_cl_all_disconnect(dev); mei_hbm_reset(dev); memset(dev->rd_msg_hdr, 0, sizeof(dev->rd_msg_hdr)); if (ret) { dev_err(dev->dev, "hw_reset failed ret = %d\n", ret); return ret; } if (state == MEI_DEV_POWER_DOWN) { dev_dbg(dev->dev, "powering down: end of reset\n"); dev->dev_state = MEI_DEV_DISABLED; return 0; } ret = mei_hw_start(dev); if (ret) { dev_err(dev->dev, "hw_start failed ret = %d\n", ret); return ret; } dev_dbg(dev->dev, "link is established start sending messages.\n"); dev->dev_state = MEI_DEV_INIT_CLIENTS; ret = mei_hbm_start_req(dev); if (ret) { dev_err(dev->dev, "hbm_start failed ret = %d\n", ret); dev->dev_state = MEI_DEV_RESETTING; return ret; } return 0; }
static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) { int result; struct usb_hcd *hcd; unsigned int virq; static u64 dummy_mask = DMA_BIT_MASK(32); if (usb_disabled()) { result = -ENODEV; goto fail_start; } result = ps3_open_hv_device(dev); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n", __func__, __LINE__); goto fail_open; } result = ps3_dma_region_create(dev->d_region); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: " "(%d)\n", __func__, __LINE__, result); BUG_ON("check region type"); goto fail_dma_region; } result = ps3_mmio_region_create(dev->m_region); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", __func__, __LINE__); result = -EPERM; goto fail_mmio_region; } dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", __func__, __LINE__, virq); result = -EPERM; goto fail_irq; } dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev_name(&dev->core)); if (!hcd) { dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, __LINE__); result = -ENOMEM; goto fail_create_hcd; } hcd->rsrc_start = dev->m_region->lpar_addr; hcd->rsrc_len = dev->m_region->len; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n", __func__, __LINE__); hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); if (!hcd->regs) { dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, __LINE__); result = -EPERM; goto fail_ioremap; } dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, (unsigned long)hcd->rsrc_start); dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, (unsigned long)hcd->rsrc_len); dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, (unsigned long)hcd->regs); dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, (unsigned long)virq); ps3_system_bus_set_drvdata(dev, hcd); result = usb_add_hcd(hcd, virq, 0); if (result) { dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", __func__, __LINE__, result); goto fail_add_hcd; } return result; fail_add_hcd: iounmap(hcd->regs); fail_ioremap: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); fail_create_hcd: ps3_io_irq_destroy(virq); fail_irq: ps3_free_mmio_region(dev->m_region); fail_mmio_region: ps3_dma_region_free(dev->d_region); fail_dma_region: ps3_close_hv_device(dev); fail_open: fail_start: return result; }
/* always call with the tx_lock held */ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd) { struct request *req = blk_mq_rq_from_pdu(cmd); int result, flags; struct nbd_request request; unsigned long size = blk_rq_bytes(req); u32 type; if (req->cmd_type == REQ_TYPE_DRV_PRIV) type = NBD_CMD_DISC; else if (req_op(req) == REQ_OP_DISCARD) type = NBD_CMD_TRIM; else if (req_op(req) == REQ_OP_FLUSH) type = NBD_CMD_FLUSH; else if (rq_data_dir(req) == WRITE) type = NBD_CMD_WRITE; else type = NBD_CMD_READ; memset(&request, 0, sizeof(request)); request.magic = htonl(NBD_REQUEST_MAGIC); request.type = htonl(type); if (type != NBD_CMD_FLUSH && type != NBD_CMD_DISC) { request.from = cpu_to_be64((u64)blk_rq_pos(req) << 9); request.len = htonl(size); } memcpy(request.handle, &req->tag, sizeof(req->tag)); dev_dbg(nbd_to_dev(nbd), "request %p: sending control (%s@%llu,%uB)\n", cmd, nbdcmd_to_ascii(type), (unsigned long long)blk_rq_pos(req) << 9, blk_rq_bytes(req)); result = sock_xmit(nbd, 1, &request, sizeof(request), (type == NBD_CMD_WRITE) ? MSG_MORE : 0); if (result <= 0) { dev_err(disk_to_dev(nbd->disk), "Send control failed (result %d)\n", result); return -EIO; } if (type == NBD_CMD_WRITE) { struct req_iterator iter; struct bio_vec bvec; /* * we are really probing at internals to determine * whether to set MSG_MORE or not... */ rq_for_each_segment(bvec, req, iter) { flags = 0; if (!rq_iter_last(bvec, iter)) flags = MSG_MORE; dev_dbg(nbd_to_dev(nbd), "request %p: sending %d bytes data\n", cmd, bvec.bv_len); result = sock_send_bvec(nbd, &bvec, flags); if (result <= 0) { dev_err(disk_to_dev(nbd->disk), "Send data failed (result %d)\n", result); return -EIO; } } }
static void sharpsl_battery_thread(struct work_struct *private_) { int voltage, percent, apm_status, i = 0; if (!sharpsl_pm.machinfo) return; sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE); /* Corgi cannot confirm when battery fully charged so periodically kick! */ if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) schedule_delayed_work(&toggle_charger, 0); while(1) { voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); if (voltage > 0) break; if (i++ > 5) { voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); break; } } voltage = sharpsl_average_value(voltage); apm_status = get_apm_status(voltage); percent = get_percentage(voltage); /* At low battery voltages, the voltage has a tendency to start creeping back up so we try to avoid this here */ if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) { sharpsl_pm.battstat.mainbat_voltage = voltage; sharpsl_pm.battstat.mainbat_status = apm_status; sharpsl_pm.battstat.mainbat_percent = percent; } dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %ld\n", voltage, sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); #ifdef CONFIG_BACKLIGHT_CORGI /* If battery is low. limit backlight intensity to save power. */ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) || (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) { if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) { sharpsl_pm.machinfo->backlight_limit(1); sharpsl_pm.flags |= SHARPSL_BL_LIMIT; } } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) { sharpsl_pm.machinfo->backlight_limit(0); sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT; } #endif /* Suspend if critical battery level */ if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { sharpsl_pm.flags |= SHARPSL_APM_QUEUED; dev_err(sharpsl_pm.dev, "Fatal Off\n"); apm_queue_event(APM_CRITICAL_SUSPEND); } schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); }
static int arizona_runtime_resume(struct device *dev) { struct arizona *arizona = dev_get_drvdata(dev); int ret; dev_dbg(arizona->dev, "Leaving AoD mode\n"); ret = regulator_enable(arizona->dcvdd); if (ret != 0) { dev_err(arizona->dev, "Failed to enable DCVDD: %d\n", ret); return ret; } regcache_cache_only(arizona->regmap, false); switch (arizona->type) { case WM5102: if (arizona->external_dcvdd) { ret = regmap_update_bits(arizona->regmap, ARIZONA_ISOLATION_CONTROL, ARIZONA_ISOLATE_DCVDD1, 0); if (ret != 0) { dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret); goto err; } } ret = wm5102_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err; } ret = arizona_apply_hardware_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply hardware patch: %d\n", ret); goto err; } break; default: ret = arizona_wait_for_boot(arizona); if (ret != 0) { goto err; } if (arizona->external_dcvdd) { ret = regmap_update_bits(arizona->regmap, ARIZONA_ISOLATION_CONTROL, ARIZONA_ISOLATE_DCVDD1, 0); if (ret != 0) { dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret); goto err; } } break; } switch (arizona->type) { case WM5102: ret = wm5102_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err; } default: break; } ret = regcache_sync(arizona->regmap); if (ret != 0) { dev_err(arizona->dev, "Failed to restore register cache\n"); goto err; } return 0; err: regcache_cache_only(arizona->regmap, true); regulator_disable(arizona->dcvdd); return ret; }
/* * Charging Control while suspended * Return 1 - go straight to sleep * Return 0 - sleep or wakeup depending on other factors */ static int sharpsl_off_charge_battery(void) { int time; dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); if (sharpsl_pm.charge_mode == CHRG_OFF) { dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); /* AC Check */ if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0)) return sharpsl_off_charge_error(); /* Start Charging */ sharpsl_pm_led(SHARPSL_LED_ON); sharpsl_pm.machinfo->charge(0); mdelay(SHARPSL_CHARGE_WAIT_TIME); sharpsl_pm.machinfo->charge(1); sharpsl_pm.charge_mode = CHRG_ON; sharpsl_pm.full_count = 0; return 1; } else if (sharpsl_pm.charge_mode != CHRG_ON) { return 1; } if (sharpsl_pm.full_count == 0) { int time; dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0)) return sharpsl_off_charge_error(); sharpsl_pm.machinfo->charge(0); mdelay(SHARPSL_CHARGE_WAIT_TIME); sharpsl_pm.machinfo->charge(1); sharpsl_pm.charge_mode = CHRG_ON; mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); time = RCNR; while(1) { /* Check if any wakeup event had occurred */ if (sharpsl_pm.machinfo->charger_wakeup() != 0) return 0; /* Check for timeout */ if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) return 1; if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occurred. Retrying to check\n"); sharpsl_pm.full_count++; sharpsl_pm.machinfo->charge(0); mdelay(SHARPSL_CHARGE_WAIT_TIME); sharpsl_pm.machinfo->charge(1); return 1; } } } dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); time = RCNR; while(1) { /* Check if any wakeup event had occurred */ if (sharpsl_pm.machinfo->charger_wakeup() != 0) return 0; /* Check for timeout */ if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); sharpsl_pm.full_count = 0; } sharpsl_pm.full_count++; return 1; } if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); sharpsl_pm_led(SHARPSL_LED_OFF); sharpsl_pm.machinfo->charge(0); sharpsl_pm.charge_mode = CHRG_DONE; return 1; } } }
static irqreturn_t synquacer_i2c_isr(int irq, void *dev_id) { struct synquacer_i2c *i2c = dev_id; unsigned char byte; unsigned char bsr, bcr; int ret; bcr = readb(i2c->base + SYNQUACER_I2C_REG_BCR); bsr = readb(i2c->base + SYNQUACER_I2C_REG_BSR); dev_dbg(i2c->dev, "bsr:0x%02x, bcr:0x%02x\n", bsr, bcr); if (bcr & SYNQUACER_I2C_BCR_BER) { dev_err(i2c->dev, "bus error\n"); synquacer_i2c_stop(i2c, -EAGAIN); goto out; } if ((bsr & SYNQUACER_I2C_BSR_AL) || !(bcr & SYNQUACER_I2C_BCR_MSS)) { dev_dbg(i2c->dev, "arbitration lost\n"); synquacer_i2c_stop(i2c, -EAGAIN); goto out; } switch (i2c->state) { case STATE_START: if (bsr & SYNQUACER_I2C_BSR_LRB) { dev_dbg(i2c->dev, "ack was not received\n"); synquacer_i2c_stop(i2c, -EAGAIN); goto out; } if (i2c->msg->flags & I2C_M_RD) i2c->state = STATE_READ; else i2c->state = STATE_WRITE; if (is_lastmsg(i2c) && i2c->msg->len == 0) { synquacer_i2c_stop(i2c, 0); goto out; } if (i2c->state == STATE_READ) goto prepare_read; /* fall through */ case STATE_WRITE: if (bsr & SYNQUACER_I2C_BSR_LRB) { dev_dbg(i2c->dev, "WRITE: No Ack\n"); synquacer_i2c_stop(i2c, -EAGAIN); goto out; } if (!is_msgend(i2c)) { writeb(i2c->msg->buf[i2c->msg_ptr++], i2c->base + SYNQUACER_I2C_REG_DAR); /* clear IRQ, and continue */ writeb(SYNQUACER_I2C_BCR_BEIE | SYNQUACER_I2C_BCR_MSS | SYNQUACER_I2C_BCR_INTE, i2c->base + SYNQUACER_I2C_REG_BCR); break; } if (is_lastmsg(i2c)) { synquacer_i2c_stop(i2c, 0); break; } dev_dbg(i2c->dev, "WRITE: Next Message\n"); i2c->msg_ptr = 0; i2c->msg_idx++; i2c->msg++; /* send the new start */ ret = synquacer_i2c_master_start(i2c, i2c->msg); if (ret < 0) { dev_dbg(i2c->dev, "restart error (%d)\n", ret); synquacer_i2c_stop(i2c, -EAGAIN); break; } i2c->state = STATE_START; break; case STATE_READ: byte = readb(i2c->base + SYNQUACER_I2C_REG_DAR); if (!(bsr & SYNQUACER_I2C_BSR_FBT)) /* data */ i2c->msg->buf[i2c->msg_ptr++] = byte; else /* address */ dev_dbg(i2c->dev, "address:0x%02x. ignore it.\n", byte); prepare_read: if (is_msglast(i2c)) { writeb(SYNQUACER_I2C_BCR_MSS | SYNQUACER_I2C_BCR_BEIE | SYNQUACER_I2C_BCR_INTE, i2c->base + SYNQUACER_I2C_REG_BCR); break; } if (!is_msgend(i2c)) { writeb(SYNQUACER_I2C_BCR_MSS | SYNQUACER_I2C_BCR_BEIE | SYNQUACER_I2C_BCR_INTE | SYNQUACER_I2C_BCR_ACK, i2c->base + SYNQUACER_I2C_REG_BCR); break; } if (is_lastmsg(i2c)) { /* last message, send stop and complete */ dev_dbg(i2c->dev, "READ: Send Stop\n"); synquacer_i2c_stop(i2c, 0); break; } dev_dbg(i2c->dev, "READ: Next Transfer\n"); i2c->msg_ptr = 0; i2c->msg_idx++; i2c->msg++; ret = synquacer_i2c_master_start(i2c, i2c->msg); if (ret < 0) { dev_dbg(i2c->dev, "restart error (%d)\n", ret); synquacer_i2c_stop(i2c, -EAGAIN); } else { i2c->state = STATE_START; } break; default: dev_err(i2c->dev, "called in err STATE (%d)\n", i2c->state); break; } out: WAIT_PCLK(10, i2c->pclkrate); return IRQ_HANDLED; }
static int s3c24xx_spi_probe(struct platform_device *pdev) { struct s3c2410_spi_info *pdata; struct s3c24xx_spi *hw; struct spi_master *master; struct resource *res; int err = 0; master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); if (master == NULL) { dev_err(&pdev->dev, "No memory for spi_master\n"); err = -ENOMEM; goto err_nomem; } hw = spi_master_get_devdata(master); memset(hw, 0, sizeof(struct s3c24xx_spi)); hw->master = master; hw->pdata = pdata = dev_get_platdata(&pdev->dev); hw->dev = &pdev->dev; if (pdata == NULL) { dev_err(&pdev->dev, "No platform data supplied\n"); err = -ENOENT; goto err_no_pdata; } platform_set_drvdata(pdev, hw); init_completion(&hw->done); /* initialise fiq handler */ s3c24xx_spi_initfiq(hw); /* setup the master state. */ /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->num_chipselect = hw->pdata->num_cs; master->bus_num = pdata->bus_num; /* setup the state for the bitbang driver */ hw->bitbang.master = hw->master; hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; hw->bitbang.chipselect = s3c24xx_spi_chipsel; hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; hw->master->setup = s3c24xx_spi_setup; hw->master->cleanup = s3c24xx_spi_cleanup; dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); /* find and map our resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); err = -ENOENT; goto err_no_iores; } hw->ioarea = request_mem_region(res->start, resource_size(res), pdev->name); if (hw->ioarea == NULL) { dev_err(&pdev->dev, "Cannot reserve region\n"); err = -ENXIO; goto err_no_iores; } hw->regs = ioremap(res->start, resource_size(res)); if (hw->regs == NULL) { dev_err(&pdev->dev, "Cannot map IO\n"); err = -ENXIO; goto err_no_iomap; } hw->irq = platform_get_irq(pdev, 0); if (hw->irq < 0) { dev_err(&pdev->dev, "No IRQ specified\n"); err = -ENOENT; goto err_no_irq; } err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); if (err) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); goto err_no_irq; } hw->clk = clk_get(&pdev->dev, "spi"); if (IS_ERR(hw->clk)) { dev_err(&pdev->dev, "No clock for device\n"); err = PTR_ERR(hw->clk); goto err_no_clk; } /* setup any gpio we can */ if (!pdata->set_cs) { if (pdata->pin_cs < 0) { dev_err(&pdev->dev, "No chipselect pin\n"); err = -EINVAL; goto err_register; } err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); if (err) { dev_err(&pdev->dev, "Failed to get gpio for cs\n"); goto err_register; } hw->set_cs = s3c24xx_spi_gpiocs; gpio_direction_output(pdata->pin_cs, 1); } else hw->set_cs = pdata->set_cs; s3c24xx_spi_initialsetup(hw); /* register our spi controller */ err = spi_bitbang_start(&hw->bitbang); if (err) { dev_err(&pdev->dev, "Failed to register SPI master\n"); goto err_register; } return 0; err_register: if (hw->set_cs == s3c24xx_spi_gpiocs) gpio_free(pdata->pin_cs); clk_disable(hw->clk); clk_put(hw->clk); err_no_clk: free_irq(hw->irq, hw); err_no_irq: iounmap(hw->regs); err_no_iomap: release_resource(hw->ioarea); kfree(hw->ioarea); err_no_iores: err_no_pdata: spi_master_put(hw->master); err_nomem: return err; }
/* * Create and register a struct regulator_dev based on the information in * a struct proccomm_regulator_info. * Fills in the rdev field in struct proccomm_regulator_info. */ static struct regulator_dev *__devinit create_proccomm_rdev( struct proccomm_regulator_info *info, struct device *parent) { const char *name; struct proccomm_regulator_drvdata *d; struct regulator_dev *rdev; int rc = 0; if (info->id < 0) { dev_err(parent, "invalid regulator id %d\n", info->id); rc = -EINVAL; goto out; } name = info->init_data.constraints.name; if (!name) { dev_err(parent, "could not register regulator with id %d: " "no name specified\n", info->id); rc = -EINVAL; goto out; } if (info->pulldown > 0) { rc = _vreg_pull_down(info->id, info->pulldown); if (rc) { dev_err(parent, "probing for regulator %d (%s) failed\n", info->id, name); goto out; } } d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) { dev_err(parent, "could not allocate struct proccomm_regulator_drvdata " "for regulator %d (%s)\n", info->id, name); rc = -ENOMEM; goto out; } d->rdesc.name = name; d->rdesc.id = info->id; d->rdesc.ops = &proccomm_regulator_ops; d->rdesc.type = REGULATOR_VOLTAGE; d->rdesc.owner = THIS_MODULE; d->rise_time = info->rise_time; d->enabled = 0; d->negative = info->negative; d->rdesc.n_voltages = info->n_voltages; rdev = regulator_register(&d->rdesc, parent, &info->init_data, d, NULL); if (IS_ERR(rdev)) { rc = PTR_ERR(rdev); dev_err(parent, "error registering regulator %d (%s): %d\n", info->id, name, rc); goto clean; } dev_dbg(parent, "registered regulator %d (%s)\n", info->id, name); return rdev; clean: kfree(d); out: return ERR_PTR(rc); }
static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, int asnum, struct usb_host_interface *ifp, int num_ep, unsigned char *buffer, int size) { unsigned char *buffer0 = buffer; struct usb_endpoint_descriptor *d; struct usb_host_endpoint *endpoint; int n, i, j, retval; d = (struct usb_endpoint_descriptor *) buffer; buffer += d->bLength; size -= d->bLength; if (d->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE) n = USB_DT_ENDPOINT_AUDIO_SIZE; else if (d->bLength >= USB_DT_ENDPOINT_SIZE) n = USB_DT_ENDPOINT_SIZE; else { dev_warn(ddev, "config %d interface %d altsetting %d has an " "invalid endpoint descriptor of length %d, skipping\n", cfgno, inum, asnum, d->bLength); goto skip_to_next_endpoint_or_interface_descriptor; } i = d->bEndpointAddress & ~USB_ENDPOINT_DIR_MASK; if (i >= 16 || i == 0) { dev_warn(ddev, "config %d interface %d altsetting %d has an " "invalid endpoint with address 0x%X, skipping\n", cfgno, inum, asnum, d->bEndpointAddress); goto skip_to_next_endpoint_or_interface_descriptor; } /* Only store as many endpoints as we have room for */ if (ifp->desc.bNumEndpoints >= num_ep) goto skip_to_next_endpoint_or_interface_descriptor; endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; ++ifp->desc.bNumEndpoints; memcpy(&endpoint->desc, d, n); INIT_LIST_HEAD(&endpoint->urb_list); /* Fix up bInterval values outside the legal range. Use 32 ms if no * proper value can be guessed. */ i = 0; /* i = min, j = max, n = default */ j = 255; if (usb_endpoint_xfer_int(d)) { i = 1; switch (to_usb_device(ddev)->speed) { case USB_SPEED_SUPER: case USB_SPEED_HIGH: /* Many device manufacturers are using full-speed * bInterval values in high-speed interrupt endpoint * descriptors. Try to fix those and fall back to a * 32 ms default value otherwise. */ n = fls(d->bInterval*8); if (n == 0) n = 9; /* 32 ms = 2^(9-1) uframes */ j = 16; /* * Adjust bInterval for quirked devices. * This quirk fixes bIntervals reported in * linear microframes. */ if (to_usb_device(ddev)->quirks & USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) { n = clamp(fls(d->bInterval), i, j); i = j = n; } break; default: /* USB_SPEED_FULL or _LOW */ /* For low-speed, 10 ms is the official minimum. * But some "overclocked" devices might want faster * polling so we'll allow it. */ n = 32; break; } } else if (usb_endpoint_xfer_isoc(d)) { i = 1; j = 16; switch (to_usb_device(ddev)->speed) { case USB_SPEED_HIGH: n = 9; /* 32 ms = 2^(9-1) uframes */ break; default: /* USB_SPEED_FULL */ n = 6; /* 32 ms = 2^(6-1) frames */ break; } } if (d->bInterval < i || d->bInterval > j) { dev_warn(ddev, "config %d interface %d altsetting %d " "endpoint 0x%X has an invalid bInterval %d, " "changing to %d\n", cfgno, inum, asnum, d->bEndpointAddress, d->bInterval, n); endpoint->desc.bInterval = n; } /* Some buggy low-speed devices have Bulk endpoints, which is * explicitly forbidden by the USB spec. In an attempt to make * them usable, we will try treating them as Interrupt endpoints. */ if (to_usb_device(ddev)->speed == USB_SPEED_LOW && usb_endpoint_xfer_bulk(d)) { dev_warn(ddev, "config %d interface %d altsetting %d " "endpoint 0x%X is Bulk; changing to Interrupt\n", cfgno, inum, asnum, d->bEndpointAddress); endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT; endpoint->desc.bInterval = 1; if (usb_endpoint_maxp(&endpoint->desc) > 8) endpoint->desc.wMaxPacketSize = cpu_to_le16(8); } /* * Some buggy high speed devices have bulk endpoints using * maxpacket sizes other than 512. High speed HCDs may not * be able to handle that particular bug, so let's warn... */ if (to_usb_device(ddev)->speed == USB_SPEED_HIGH && usb_endpoint_xfer_bulk(d)) { unsigned maxp; maxp = usb_endpoint_maxp(&endpoint->desc) & 0x07ff; if (maxp != 512) dev_warn(ddev, "config %d interface %d altsetting %d " "bulk endpoint 0x%X has invalid maxpacket %d\n", cfgno, inum, asnum, d->bEndpointAddress, maxp); } /* Parse a possible SuperSpeed endpoint companion descriptor */ if (to_usb_device(ddev)->speed == USB_SPEED_SUPER) usb_parse_ss_endpoint_companion(ddev, cfgno, inum, asnum, endpoint, buffer, size); /* Skip over any Class Specific or Vendor Specific descriptors; * find the next endpoint or interface descriptor */ endpoint->extra = buffer; i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, USB_DT_INTERFACE, &n); endpoint->extralen = i; retval = buffer - buffer0 + i; if (n > 0) dev_dbg(ddev, "skipped %d descriptor%s after %s\n", n, plural(n), "endpoint"); return retval; skip_to_next_endpoint_or_interface_descriptor: i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, USB_DT_INTERFACE, NULL); return buffer - buffer0 + i; }
static int ehci_mxc_drv_probe(struct platform_device *pdev) { struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data; struct usb_hcd *hcd; struct resource *res; int irq, ret; unsigned int flags; struct ehci_mxc_priv *priv; struct device *dev = &pdev->dev; struct ehci_hcd *ehci; dev_info(&pdev->dev, "initializing i.MX USB Controller\n"); if (!pdata) { dev_err(dev, "No platform data given, bailing out.\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); hcd = usb_create_hcd(&ehci_mxc_hc_driver, dev, dev_name(dev)); if (!hcd) return -ENOMEM; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { ret = -ENOMEM; goto err_alloc; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "Found HC with no register addr. Check setup!\n"); ret = -ENODEV; goto err_get_resource; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(dev, "controller already in use\n"); ret = -EBUSY; goto err_request_mem; } hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_err(dev, "error mapping memory\n"); ret = -EFAULT; goto err_ioremap; } /* enable clocks */ priv->usbclk = clk_get(dev, "usb"); if (IS_ERR(priv->usbclk)) { ret = PTR_ERR(priv->usbclk); goto err_clk; } clk_enable(priv->usbclk); if (!cpu_is_mx35() && !cpu_is_mx25()) { priv->ahbclk = clk_get(dev, "usb_ahb"); if (IS_ERR(priv->ahbclk)) { ret = PTR_ERR(priv->ahbclk); goto err_clk_ahb; } clk_enable(priv->ahbclk); } /* "dr" device has its own clock on i.MX51 */ if (cpu_is_mx51() && (pdev->id == 0)) { priv->phy1clk = clk_get(dev, "usb_phy1"); if (IS_ERR(priv->phy1clk)) { ret = PTR_ERR(priv->phy1clk); goto err_clk_phy; } clk_enable(priv->phy1clk); } /* call platform specific init function */ if (pdata->init) { ret = pdata->init(pdev); if (ret) { dev_err(dev, "platform init failed\n"); goto err_init; } /* platforms need some time to settle changed IO settings */ mdelay(10); } ehci = hcd_to_ehci(hcd); /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; ehci->regs = hcd->regs + 0x100 + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); /* set up the PORTSCx register */ ehci_writel(ehci, pdata->portsc, &ehci->regs->port_status[0]); /* is this really needed? */ msleep(10); /* Initialize the transceiver */ if (pdata->otg) { pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; ret = otg_init(pdata->otg); if (ret) { dev_err(dev, "unable to init transceiver, probably missing\n"); ret = -ENODEV; goto err_add; } ret = otg_set_vbus(pdata->otg, 1); if (ret) { dev_err(dev, "unable to enable vbus on transceiver\n"); goto err_add; } } priv->hcd = hcd; platform_set_drvdata(pdev, priv); ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (ret) goto err_add; if (pdata->otg) { /* * efikamx and efikasb have some hardware bug which is * preventing usb to work unless CHRGVBUS is set. * It's in violation of USB specs */ if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) { flags = otg_io_read(pdata->otg, ULPI_OTG_CTRL); flags |= ULPI_OTG_CTRL_CHRGVBUS; ret = otg_io_write(pdata->otg, flags, ULPI_OTG_CTRL); if (ret) { dev_err(dev, "unable to set CHRVBUS\n"); goto err_add; } } } return 0; err_add: if (pdata && pdata->exit) pdata->exit(pdev); err_init: if (priv->phy1clk) { clk_disable(priv->phy1clk); clk_put(priv->phy1clk); } err_clk_phy: if (priv->ahbclk) { clk_disable(priv->ahbclk); clk_put(priv->ahbclk); } err_clk_ahb: clk_disable(priv->usbclk); clk_put(priv->usbclk); err_clk: iounmap(hcd->regs); err_ioremap: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_request_mem: err_get_resource: kfree(priv); err_alloc: usb_put_hcd(hcd); return ret; }
static int usb_parse_interface(struct device *ddev, int cfgno, struct usb_host_config *config, unsigned char *buffer, int size, u8 inums[], u8 nalts[]) { unsigned char *buffer0 = buffer; struct usb_interface_descriptor *d; int inum, asnum; struct usb_interface_cache *intfc; struct usb_host_interface *alt; int i, n; int len, retval; int num_ep, num_ep_orig; d = (struct usb_interface_descriptor *) buffer; buffer += d->bLength; size -= d->bLength; if (d->bLength < USB_DT_INTERFACE_SIZE) goto skip_to_next_interface_descriptor; /* Which interface entry is this? */ intfc = NULL; inum = d->bInterfaceNumber; for (i = 0; i < config->desc.bNumInterfaces; ++i) { if (inums[i] == inum) { intfc = config->intf_cache[i]; break; } } if (!intfc || intfc->num_altsetting >= nalts[i]) goto skip_to_next_interface_descriptor; /* Check for duplicate altsetting entries */ asnum = d->bAlternateSetting; for ((i = 0, alt = &intfc->altsetting[0]); i < intfc->num_altsetting; (++i, ++alt)) { if (alt->desc.bAlternateSetting == asnum) { dev_warn(ddev, "Duplicate descriptor for config %d " "interface %d altsetting %d, skipping\n", cfgno, inum, asnum); goto skip_to_next_interface_descriptor; } } ++intfc->num_altsetting; memcpy(&alt->desc, d, USB_DT_INTERFACE_SIZE); /* Skip over any Class Specific or Vendor Specific descriptors; * find the first endpoint or interface descriptor */ alt->extra = buffer; i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, USB_DT_INTERFACE, &n); alt->extralen = i; if (n > 0) dev_dbg(ddev, "skipped %d descriptor%s after %s\n", n, plural(n), "interface"); buffer += i; size -= i; /* Allocate space for the right(?) number of endpoints */ num_ep = num_ep_orig = alt->desc.bNumEndpoints; alt->desc.bNumEndpoints = 0; /* Use as a counter */ if (num_ep > USB_MAXENDPOINTS) { dev_warn(ddev, "too many endpoints for config %d interface %d " "altsetting %d: %d, using maximum allowed: %d\n", cfgno, inum, asnum, num_ep, USB_MAXENDPOINTS); num_ep = USB_MAXENDPOINTS; } if (num_ep > 0) { /* Can't allocate 0 bytes */ len = sizeof(struct usb_host_endpoint) * num_ep; alt->endpoint = kzalloc(len, GFP_KERNEL); if (!alt->endpoint) return -ENOMEM; } /* Parse all the endpoint descriptors */ n = 0; while (size > 0) { if (((struct usb_descriptor_header *) buffer)->bDescriptorType == USB_DT_INTERFACE) break; retval = usb_parse_endpoint(ddev, cfgno, inum, asnum, alt, num_ep, buffer, size); if (retval < 0) return retval; ++n; buffer += retval; size -= retval; } if (n != num_ep_orig) dev_warn(ddev, "config %d interface %d altsetting %d has %d " "endpoint descriptor%s, different from the interface " "descriptor's value: %d\n", cfgno, inum, asnum, n, plural(n), num_ep_orig); return buffer - buffer0; skip_to_next_interface_descriptor: i = find_next_descriptor(buffer, size, USB_DT_INTERFACE, USB_DT_INTERFACE, NULL); return buffer - buffer0 + i; }
static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream) { struct atmel_ac97c *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; int block_size = frames_to_bytes(runtime, runtime->period_size); unsigned long word = ac97c_readl(chip, ICA); int retval; chip->capture_period = 0; word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); /* assign channels to AC97C channel A */ switch (runtime->channels) { case 1: word |= AC97C_CH_ASSIGN(PCM_LEFT, A); break; case 2: word |= AC97C_CH_ASSIGN(PCM_LEFT, A) | AC97C_CH_ASSIGN(PCM_RIGHT, A); break; default: /* TODO: support more than two channels */ return -EINVAL; } ac97c_writel(chip, ICA, word); /* configure sample format and size */ word = ac97c_readl(chip, CAMR); if (chip->opened <= 1) word = AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; else word |= AC97C_CMR_DMAEN | AC97C_CMR_SIZE_16; switch (runtime->format) { case SNDRV_PCM_FORMAT_S16_LE: if (cpu_is_at32ap7000()) word |= AC97C_CMR_CEM_LITTLE; break; case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ word &= ~(AC97C_CMR_CEM_LITTLE); break; default: word = ac97c_readl(chip, ICA); word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT)); ac97c_writel(chip, ICA, word); return -EINVAL; } /* Enable overrun interrupt on channel A */ word |= AC97C_CSR_OVRUN; ac97c_writel(chip, CAMR, word); /* Enable channel A event interrupt */ word = ac97c_readl(chip, IMR); word |= AC97C_SR_CAEVT; ac97c_writel(chip, IER, word); /* set variable rate if needed */ if (runtime->rate != 48000) { word = ac97c_readl(chip, MR); word |= AC97C_MR_VRA; ac97c_writel(chip, MR, word); } else { word = ac97c_readl(chip, MR); word &= ~(AC97C_MR_VRA); ac97c_writel(chip, MR, word); } retval = snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); if (retval) dev_dbg(&chip->pdev->dev, "could not set rate %d Hz\n", runtime->rate); if (cpu_is_at32ap7000()) { if (!test_bit(DMA_RX_READY, &chip->flags)) retval = atmel_ac97c_prepare_dma(chip, substream, DMA_DEV_TO_MEM); } else { /* Initialize and start the PDC */ writel(runtime->dma_addr, chip->regs + ATMEL_PDC_RPR); writel(block_size / 2, chip->regs + ATMEL_PDC_RCR); writel(runtime->dma_addr + block_size, chip->regs + ATMEL_PDC_RNPR); writel(block_size / 2, chip->regs + ATMEL_PDC_RNCR); } return retval; }
static int usb_parse_configuration(struct usb_device *dev, int cfgidx, struct usb_host_config *config, unsigned char *buffer, int size) { struct device *ddev = &dev->dev; unsigned char *buffer0 = buffer; int cfgno; int nintf, nintf_orig; int i, j, n; struct usb_interface_cache *intfc; unsigned char *buffer2; int size2; struct usb_descriptor_header *header; int len, retval; u8 inums[USB_MAXINTERFACES], nalts[USB_MAXINTERFACES]; unsigned iad_num = 0; memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); if (config->desc.bDescriptorType != USB_DT_CONFIG || config->desc.bLength < USB_DT_CONFIG_SIZE || config->desc.bLength > size) { dev_err(ddev, "invalid descriptor for config index %d: " "type = 0x%X, length = %d\n", cfgidx, config->desc.bDescriptorType, config->desc.bLength); return -EINVAL; } cfgno = config->desc.bConfigurationValue; buffer += config->desc.bLength; size -= config->desc.bLength; nintf = nintf_orig = config->desc.bNumInterfaces; if (nintf > USB_MAXINTERFACES) { dev_warn(ddev, "config %d has too many interfaces: %d, " "using maximum allowed: %d\n", cfgno, nintf, USB_MAXINTERFACES); nintf = USB_MAXINTERFACES; } /* Go through the descriptors, checking their length and counting the * number of altsettings for each interface */ n = 0; for ((buffer2 = buffer, size2 = size); size2 > 0; (buffer2 += header->bLength, size2 -= header->bLength)) { if (size2 < sizeof(struct usb_descriptor_header)) { dev_warn(ddev, "config %d descriptor has %d excess " "byte%s, ignoring\n", cfgno, size2, plural(size2)); break; } header = (struct usb_descriptor_header *) buffer2; if ((header->bLength > size2) || (header->bLength < 2)) { dev_warn(ddev, "config %d has an invalid descriptor " "of length %d, skipping remainder of the config\n", cfgno, header->bLength); break; } if (header->bDescriptorType == USB_DT_INTERFACE) { struct usb_interface_descriptor *d; int inum; d = (struct usb_interface_descriptor *) header; if (d->bLength < USB_DT_INTERFACE_SIZE) { dev_warn(ddev, "config %d has an invalid " "interface descriptor of length %d, " "skipping\n", cfgno, d->bLength); continue; } inum = d->bInterfaceNumber; if ((dev->quirks & USB_QUIRK_HONOR_BNUMINTERFACES) && n >= nintf_orig) { dev_warn(ddev, "config %d has more interface " "descriptors, than it declares in " "bNumInterfaces, ignoring interface " "number: %d\n", cfgno, inum); continue; } if (inum >= nintf_orig) dev_warn(ddev, "config %d has an invalid " "interface number: %d but max is %d\n", cfgno, inum, nintf_orig - 1); /* Have we already encountered this interface? * Count its altsettings */ for (i = 0; i < n; ++i) { if (inums[i] == inum) break; } if (i < n) { if (nalts[i] < 255) ++nalts[i]; } else if (n < USB_MAXINTERFACES) { inums[n] = inum; nalts[n] = 1; ++n; } } else if (header->bDescriptorType == USB_DT_INTERFACE_ASSOCIATION) { if (iad_num == USB_MAXIADS) { dev_warn(ddev, "found more Interface " "Association Descriptors " "than allocated for in " "configuration %d\n", cfgno); } else { config->intf_assoc[iad_num] = (struct usb_interface_assoc_descriptor *)header; iad_num++; } } else if (header->bDescriptorType == USB_DT_DEVICE || header->bDescriptorType == USB_DT_CONFIG) dev_warn(ddev, "config %d contains an unexpected " "descriptor of type 0x%X, skipping\n", cfgno, header->bDescriptorType); } /* for ((buffer2 = buffer, size2 = size); ...) */ size = buffer2 - buffer; config->desc.wTotalLength = cpu_to_le16(buffer2 - buffer0); if (n != nintf) dev_warn(ddev, "config %d has %d interface%s, different from " "the descriptor's value: %d\n", cfgno, n, plural(n), nintf_orig); else if (n == 0) dev_warn(ddev, "config %d has no interfaces?\n", cfgno); config->desc.bNumInterfaces = nintf = n; /* Check for missing interface numbers */ for (i = 0; i < nintf; ++i) { for (j = 0; j < nintf; ++j) { if (inums[j] == i) break; } if (j >= nintf) dev_warn(ddev, "config %d has no interface number " "%d\n", cfgno, i); } /* Allocate the usb_interface_caches and altsetting arrays */ for (i = 0; i < nintf; ++i) { j = nalts[i]; if (j > USB_MAXALTSETTING) { dev_warn(ddev, "too many alternate settings for " "config %d interface %d: %d, " "using maximum allowed: %d\n", cfgno, inums[i], j, USB_MAXALTSETTING); nalts[i] = j = USB_MAXALTSETTING; } len = sizeof(*intfc) + sizeof(struct usb_host_interface) * j; config->intf_cache[i] = intfc = kzalloc(len, GFP_KERNEL); if (!intfc) return -ENOMEM; kref_init(&intfc->ref); } /* FIXME: parse the BOS descriptor */ /* Skip over any Class Specific or Vendor Specific descriptors; * find the first interface descriptor */ config->extra = buffer; i = find_next_descriptor(buffer, size, USB_DT_INTERFACE, USB_DT_INTERFACE, &n); config->extralen = i; if (n > 0) dev_dbg(ddev, "skipped %d descriptor%s after %s\n", n, plural(n), "configuration"); buffer += i; size -= i; /* Parse all the interface/altsetting descriptors */ while (size > 0) { retval = usb_parse_interface(ddev, cfgno, config, buffer, size, inums, nalts); if (retval < 0) return retval; buffer += retval; size -= retval; } /* Check for missing altsettings */ for (i = 0; i < nintf; ++i) { intfc = config->intf_cache[i]; for (j = 0; j < intfc->num_altsetting; ++j) { for (n = 0; n < intfc->num_altsetting; ++n) { if (intfc->altsetting[n].desc. bAlternateSetting == j) break; } if (n >= intfc->num_altsetting) dev_warn(ddev, "config %d interface %d has no " "altsetting %d\n", cfgno, inums[i], j); } } return 0; }
static int max98926_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { int dai_sr = -EINVAL; int rate = params_rate(params), i; struct snd_soc_codec *codec = dai->codec; struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec); int blr_clk_ratio; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: regmap_update_bits(max98926->regmap, MAX98926_FORMAT, MAX98926_DAI_CHANSZ_MASK, MAX98926_DAI_CHANSZ_16); max98926->ch_size = 16; break; case SNDRV_PCM_FORMAT_S24_LE: regmap_update_bits(max98926->regmap, MAX98926_FORMAT, MAX98926_DAI_CHANSZ_MASK, MAX98926_DAI_CHANSZ_24); max98926->ch_size = 24; break; case SNDRV_PCM_FORMAT_S32_LE: regmap_update_bits(max98926->regmap, MAX98926_FORMAT, MAX98926_DAI_CHANSZ_MASK, MAX98926_DAI_CHANSZ_32); max98926->ch_size = 32; break; default: dev_dbg(codec->dev, "format unsupported %d\n", params_format(params)); return -EINVAL; } /* BCLK/LRCLK ratio calculation */ blr_clk_ratio = params_channels(params) * max98926->ch_size; switch (blr_clk_ratio) { case 32: regmap_update_bits(max98926->regmap, MAX98926_DAI_CLK_MODE2, MAX98926_DAI_BSEL_MASK, MAX98926_DAI_BSEL_32); break; case 48: regmap_update_bits(max98926->regmap, MAX98926_DAI_CLK_MODE2, MAX98926_DAI_BSEL_MASK, MAX98926_DAI_BSEL_48); break; case 64: regmap_update_bits(max98926->regmap, MAX98926_DAI_CLK_MODE2, MAX98926_DAI_BSEL_MASK, MAX98926_DAI_BSEL_64); break; default: return -EINVAL; } /* find the closest rate */ for (i = 0; i < ARRAY_SIZE(rate_table); i++) { if (rate_table[i].rate >= rate) { dai_sr = rate_table[i].sr; break; } } if (dai_sr < 0) return -EINVAL; /* set DAI_SR to correct LRCLK frequency */ regmap_update_bits(max98926->regmap, MAX98926_DAI_CLK_MODE2, MAX98926_DAI_SR_MASK, dai_sr << MAX98926_DAI_SR_SHIFT); return 0; }
static void max14577_set_charging(struct sec_charger_info *charger) { union power_supply_propval val; int full_check_type; u8 data; if (charger->cable_type == POWER_SUPPLY_TYPE_BATTERY) { /* turn off charger */ data = 0x80; max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL2, data); } else { /* Battery Fast-Charge Timer disabled [6:4] = 0b111 */ data = 0x70; max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL1, data); /* Battery-Charger Constant Voltage(CV) Mode, float voltage */ data = 0; data |= max14577_get_float_voltage_data( charger->pdata->chg_float_voltage); dev_dbg(&charger->client->dev, "%s : float voltage (%dmV)\n", __func__, charger->pdata->chg_float_voltage); max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL3, data); /* Fast Battery Charge Current */ data = 0; data |= max14577_get_fast_charging_current_data( charger->charging_current); dev_dbg(&charger->client->dev, "%s : charging current (%dmA)\n", __func__, charger->charging_current); max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL4, data); /* End-of-Charge Current Setting */ data = 0; psy_do_property("battery", get, POWER_SUPPLY_PROP_CHARGE_NOW, val); if (val.intval == SEC_BATTERY_CHARGING_1ST) full_check_type = charger->pdata->full_check_type; else full_check_type = charger->pdata->full_check_type_2nd; switch (full_check_type) { case SEC_BATTERY_FULLCHARGED_CHGGPIO: case SEC_BATTERY_FULLCHARGED_CHGINT: case SEC_BATTERY_FULLCHARGED_CHGPSY: if (val.intval == SEC_BATTERY_CHARGING_1ST) { data |= max14577_get_term_current_data( charger->pdata->charging_current[ charger->cable_type]. full_check_current_1st); dev_dbg(&charger->client->dev, "%s : term current (%dmA)\n", __func__, charger->pdata->charging_current[ charger->cable_type]. full_check_current_1st); } else { data |= max14577_get_term_current_data( charger->pdata->charging_current[ charger->cable_type]. full_check_current_2nd); dev_dbg(&charger->client->dev, "%s : term current (%dmA)\n", __func__, charger->pdata->charging_current[ charger->cable_type]. full_check_current_2nd); } break; } max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL5, data); /* Auto Charging Stop disabled [5] = 0 */ data = 0; max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL6, data); /* Overvoltage-Protection Threshold 6.5V [1:0] = 0b10 */ data = 0x02; max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL7, data); /* turn on charger */ data = 0xc0; max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL2, data); } }
/* * ======== dsp_init ======== * Allocates bridge resources. Loads a base image onto DSP, if specified. */ u32 dsp_init(u32 *init_status) { char dev_node[MAXREGPATHLENGTH] = "TIOMAP1510"; int status = -EPERM; struct drv_object *drv_obj = NULL; u32 device_node; u32 device_node_string; if (!api_init()) goto func_cont; status = drv_create(&drv_obj); if (status) { api_exit(); goto func_cont; } /* End drv_create */ /* Request Resources */ status = drv_request_resources((u32) &dev_node, &device_node_string); if (!status) { /* Attempt to Start the Device */ status = dev_start_device((struct cfg_devnode *) device_node_string); if (status) (void)drv_release_resources ((u32) device_node_string, drv_obj); } else { dev_dbg(bridge, "%s: drv_request_resources Failed\n", __func__); status = -EPERM; } /* Unwind whatever was loaded */ if (status) { /* irrespective of the status of dev_remove_device we conitinue * unloading. Get the Driver Object iterate through and remove. * Reset the status to E_FAIL to avoid going through * api_init_complete2. */ for (device_node = drv_get_first_dev_extension(); device_node != 0; device_node = drv_get_next_dev_extension(device_node)) { (void)dev_remove_device((struct cfg_devnode *) device_node); (void)drv_release_resources((u32) device_node, drv_obj); } /* Remove the Driver Object */ (void)drv_destroy(drv_obj); drv_obj = NULL; api_exit(); dev_dbg(bridge, "%s: Logical device failed init\n", __func__); } /* Unwinding the loaded drivers */ func_cont: /* Attempt to Start the Board */ if (!status) { /* BRD_AutoStart could fail if the dsp execuetable is not the * correct one. We should not propagate that error * into the device loader. */ (void)api_init_complete2(); } else { dev_dbg(bridge, "%s: Failed\n", __func__); } /* End api_init_complete2 */ DBC_ENSURE((!status && drv_obj != NULL) || (status && drv_obj == NULL)); *init_status = status; /* Return the Driver Object */ return (u32) drv_obj; }
static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); struct mxs_saif *master_saif; u32 delay; master_saif = mxs_saif_get_master(saif); if (!master_saif) return -EINVAL; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: dev_dbg(cpu_dai->dev, "start\n"); clk_enable(master_saif->clk); if (!master_saif->mclk_in_use) __raw_writel(BM_SAIF_CTRL_RUN, master_saif->base + SAIF_CTRL + MXS_SET_ADDR); /* */ if (saif != master_saif) { clk_enable(saif->clk); __raw_writel(BM_SAIF_CTRL_RUN, saif->base + SAIF_CTRL + MXS_SET_ADDR); } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* */ __raw_writel(0, saif->base + SAIF_DATA); } else { /* */ __raw_readl(saif->base + SAIF_DATA); } master_saif->ongoing = 1; dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n", __raw_readl(saif->base + SAIF_CTRL), __raw_readl(saif->base + SAIF_STAT)); dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n", __raw_readl(master_saif->base + SAIF_CTRL), __raw_readl(master_saif->base + SAIF_STAT)); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: dev_dbg(cpu_dai->dev, "stop\n"); /* */ delay = USEC_PER_SEC / master_saif->cur_rate; if (!master_saif->mclk_in_use) { __raw_writel(BM_SAIF_CTRL_RUN, master_saif->base + SAIF_CTRL + MXS_CLR_ADDR); udelay(delay); } clk_disable(master_saif->clk); if (saif != master_saif) { __raw_writel(BM_SAIF_CTRL_RUN, saif->base + SAIF_CTRL + MXS_CLR_ADDR); udelay(delay); clk_disable(saif->clk); } master_saif->ongoing = 0; break; default: return -EINVAL; } return 0; }