static int ip101a_g_probe(struct phy_device *phydev) { struct device *dev = &phydev->mdio.dev; struct ip101a_g_phy_priv *priv; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; /* Both functions (RX error and interrupt status) are sharing the same * pin on the 32-pin IP101GR, so this is an exclusive choice. */ if (device_property_read_bool(dev, "icplus,select-rx-error") && device_property_read_bool(dev, "icplus,select-interrupt")) { dev_err(dev, "RXER and INTR mode cannot be selected together\n"); return -EINVAL; } if (device_property_read_bool(dev, "icplus,select-rx-error")) priv->sel_intr32 = IP101GR_SEL_INTR32_RXER; else if (device_property_read_bool(dev, "icplus,select-interrupt")) priv->sel_intr32 = IP101GR_SEL_INTR32_INTR; else priv->sel_intr32 = IP101GR_SEL_INTR32_KEEP; phydev->priv = priv; return 0; }
static int st_nci_spi_probe(struct spi_device *dev) { struct st_nci_spi_phy *phy; int r; dev_dbg(&dev->dev, "%s\n", __func__); dev_dbg(&dev->dev, "IRQ: %d\n", dev->irq); /* Check SPI platform functionnalities */ if (!dev) { pr_debug("%s: dev is NULL. Device is not accessible.\n", __func__); return -ENODEV; } phy = devm_kzalloc(&dev->dev, sizeof(struct st_nci_spi_phy), GFP_KERNEL); if (!phy) return -ENOMEM; phy->spi_dev = dev; spi_set_drvdata(dev, phy); r = devm_acpi_dev_add_driver_gpios(&dev->dev, acpi_st_nci_gpios); if (r) dev_dbg(&dev->dev, "Unable to add GPIO mapping table\n"); /* Get RESET GPIO */ phy->gpiod_reset = devm_gpiod_get(&dev->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(phy->gpiod_reset)) { nfc_err(&dev->dev, "Unable to get RESET GPIO\n"); return PTR_ERR(phy->gpiod_reset); } phy->se_status.is_ese_present = device_property_read_bool(&dev->dev, "ese-present"); phy->se_status.is_uicc_present = device_property_read_bool(&dev->dev, "uicc-present"); r = ndlc_probe(phy, &spi_phy_ops, &dev->dev, ST_NCI_FRAME_HEADROOM, ST_NCI_FRAME_TAILROOM, &phy->ndlc, &phy->se_status); if (r < 0) { nfc_err(&dev->dev, "Unable to register ndlc layer\n"); return r; } phy->irq_active = true; r = devm_request_threaded_irq(&dev->dev, dev->irq, NULL, st_nci_irq_thread_fn, IRQF_ONESHOT, ST_NCI_SPI_DRIVER_NAME, phy); if (r < 0) nfc_err(&dev->dev, "Unable to register IRQ handler\n"); return r; }
static int silead_ts_request_input_dev(struct silead_ts_data *data) { struct device *dev = &data->client->dev; int error; data->input = devm_input_allocate_device(dev); if (!data->input) { dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } input_set_abs_params(data->input, ABS_MT_POSITION_X, 0, 4095, 0, 0); input_set_abs_params(data->input, ABS_MT_POSITION_Y, 0, 4095, 0, 0); touchscreen_parse_properties(data->input, true, &data->prop); input_mt_init_slots(data->input, data->max_fingers, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); if (device_property_read_bool(dev, "silead,home-button")) input_set_capability(data->input, EV_KEY, KEY_LEFTMETA); data->input->name = SILEAD_TS_NAME; data->input->phys = "input/ts"; data->input->id.bustype = BUS_I2C; error = input_register_device(data->input); if (error) { dev_err(dev, "Failed to register input device: %d\n", error); return error; } return 0; }
static int gpio_poweroff_probe(struct platform_device *pdev) { bool input = false; enum gpiod_flags flags; /* If a pm_power_off function has already been added, leave it alone */ if (pm_power_off != NULL) { dev_err(&pdev->dev, "%s: pm_power_off function already registered", __func__); return -EBUSY; } input = device_property_read_bool(&pdev->dev, "input"); if (input) flags = GPIOD_IN; else flags = GPIOD_OUT_LOW; device_property_read_u32(&pdev->dev, "active-delay-ms", &active_delay); device_property_read_u32(&pdev->dev, "inactive-delay-ms", &inactive_delay); device_property_read_u32(&pdev->dev, "timeout-ms", &timeout); reset_gpio = devm_gpiod_get(&pdev->dev, NULL, flags); if (IS_ERR(reset_gpio)) return PTR_ERR(reset_gpio); pm_power_off = &gpio_poweroff_do_poweroff; return 0; }
static int max98373_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { int ret = 0; int reg = 0; struct max98373_priv *max98373 = NULL; max98373 = devm_kzalloc(&i2c->dev, sizeof(*max98373), GFP_KERNEL); if (!max98373) { ret = -ENOMEM; return ret; } i2c_set_clientdata(i2c, max98373); /* update interleave mode info */ if (device_property_read_bool(&i2c->dev, "maxim,interleave_mode")) max98373->interleave_mode = 1; else max98373->interleave_mode = 0; /* regmap initialization */ max98373->regmap = devm_regmap_init_i2c(i2c, &max98373_regmap); if (IS_ERR(max98373->regmap)) { ret = PTR_ERR(max98373->regmap); dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); return ret; } /* Check Revision ID */ ret = regmap_read(max98373->regmap, MAX98373_R21FF_REV_ID, ®); if (ret < 0) { dev_err(&i2c->dev, "Failed to read: 0x%02X\n", MAX98373_R21FF_REV_ID); return ret; } dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg); /* voltage/current slot configuration */ max98373_slot_config(i2c, max98373); /* codec registeration */ ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373, max98373_dai, ARRAY_SIZE(max98373_dai)); if (ret < 0) dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); return ret; }
static int stts751_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct stts751_priv *priv; int ret; bool smbus_nto; int rev_id; priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->client = client; priv->notify_max = true; priv->notify_min = true; i2c_set_clientdata(client, priv); mutex_init(&priv->access_lock); if (device_property_present(&client->dev, "smbus-timeout-disable")) { smbus_nto = device_property_read_bool(&client->dev, "smbus-timeout-disable"); ret = i2c_smbus_write_byte_data(client, STTS751_REG_SMBUS_TO, smbus_nto ? 0 : 0x80); if (ret) return ret; } rev_id = i2c_smbus_read_byte_data(client, STTS751_REG_REV_ID); if (rev_id < 0) return -ENODEV; if (rev_id != 0x1) { dev_dbg(&client->dev, "Chip revision 0x%x is untested\n", rev_id); } ret = stts751_read_chip_config(priv); if (ret) return ret; priv->config &= ~(STTS751_CONF_STOP | STTS751_CONF_EVENT_DIS); ret = i2c_smbus_write_byte_data(client, STTS751_REG_CONF, priv->config); if (ret) return ret; priv->dev = devm_hwmon_device_register_with_groups(&client->dev, client->name, priv, stts751_groups); return PTR_ERR_OR_ZERO(priv->dev); }
static void dwc2_get_device_property(struct dwc2_hsotg *hsotg, char *property, u8 size, u64 *value) { u8 val8; u16 val16; u32 val32; switch (size) { case 0: *value = device_property_read_bool(hsotg->dev, property); break; case 1: if (device_property_read_u8(hsotg->dev, property, &val8)) return; *value = val8; break; case 2: if (device_property_read_u16(hsotg->dev, property, &val16)) return; *value = val16; break; case 4: if (device_property_read_u32(hsotg->dev, property, &val32)) return; *value = val32; break; case 8: if (device_property_read_u64(hsotg->dev, property, value)) return; break; default: /* * The size is checked by the only function that calls * this so this should never happen. */ WARN_ON(1); return; } }
static void us5182d_get_platform_data(struct iio_dev *indio_dev) { struct us5182d_data *data = iio_priv(indio_dev); if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef", &data->ga)) data->ga = US5182D_GA_RESOLUTION; if (device_property_read_u16_array(&data->client->dev, "upisemi,dark-ths", data->us5182d_dark_ths, ARRAY_SIZE(us5182d_dark_ths_vals))) data->us5182d_dark_ths = us5182d_dark_ths_vals; if (device_property_read_u8(&data->client->dev, "upisemi,upper-dark-gain", &data->upper_dark_gain)) data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT; if (device_property_read_u8(&data->client->dev, "upisemi,lower-dark-gain", &data->lower_dark_gain)) data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT; data->default_continuous = device_property_read_bool(&data->client->dev, "upisemi,continuous"); }
static int xhci_histb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct xhci_hcd_histb *histb; const struct hc_driver *driver; struct usb_hcd *hcd; struct xhci_hcd *xhci; struct resource *res; int irq; int ret = -ENODEV; if (usb_disabled()) return -ENODEV; driver = &xhci_histb_hc_driver; histb = devm_kzalloc(dev, sizeof(*histb), GFP_KERNEL); if (!histb) return -ENOMEM; histb->dev = dev; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); histb->ctrl = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(histb->ctrl)) return PTR_ERR(histb->ctrl); ret = xhci_histb_clks_get(histb); if (ret) return ret; histb->soft_reset = devm_reset_control_get(dev, "soft"); if (IS_ERR(histb->soft_reset)) { dev_err(dev, "failed to get soft reset\n"); return PTR_ERR(histb->soft_reset); } pm_runtime_enable(dev); pm_runtime_get_sync(dev); device_enable_async_suspend(dev); /* Initialize dma_mask and coherent_dma_mask to 32-bits */ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); if (ret) return ret; hcd = usb_create_hcd(driver, dev, dev_name(dev)); if (!hcd) { ret = -ENOMEM; goto disable_pm; } hcd->regs = histb->ctrl; hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); histb->hcd = hcd; dev_set_drvdata(hcd->self.controller, histb); ret = xhci_histb_host_enable(histb); if (ret) goto put_hcd; xhci = hcd_to_xhci(hcd); device_wakeup_enable(hcd->self.controller); xhci->main_hcd = hcd; xhci->shared_hcd = usb_create_shared_hcd(driver, dev, dev_name(dev), hcd); if (!xhci->shared_hcd) { ret = -ENOMEM; goto disable_host; } if (device_property_read_bool(dev, "usb2-lpm-disable")) xhci->quirks |= XHCI_HW_LPM_DISABLE; if (device_property_read_bool(dev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; /* imod_interval is the interrupt moderation value in nanoseconds. */ xhci->imod_interval = 40000; device_property_read_u32(dev, "imod-interval-ns", &xhci->imod_interval); ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto put_usb3_hcd; if (HCC_MAX_PSA(xhci->hcc_params) >= 4) xhci->shared_hcd->can_do_streams = 1; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (ret) goto dealloc_usb2_hcd; device_enable_async_suspend(dev); pm_runtime_put_noidle(dev); /* * Prevent runtime pm from being on as default, users should enable * runtime pm using power/control in sysfs. */ pm_runtime_forbid(dev); return 0; dealloc_usb2_hcd: usb_remove_hcd(hcd); put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); disable_host: xhci_histb_host_disable(histb); put_hcd: usb_put_hcd(hcd); disable_pm: pm_runtime_put_sync(dev); pm_runtime_disable(dev); return ret; }
/* * Translate properties into platform_data */ static struct gpio_keys_platform_data * gpio_keys_get_devtree_pdata(struct device *dev) { struct gpio_keys_platform_data *pdata; struct gpio_keys_button *button; struct fwnode_handle *child; int nbuttons; nbuttons = device_get_child_node_count(dev); if (nbuttons == 0) return ERR_PTR(-ENODEV); pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * sizeof(*button), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM); button = (struct gpio_keys_button *)(pdata + 1); pdata->buttons = button; pdata->nbuttons = nbuttons; pdata->rep = device_property_read_bool(dev, "autorepeat"); device_property_read_string(dev, "label", &pdata->name); device_for_each_child_node(dev, child) { if (is_of_node(child)) button->irq = irq_of_parse_and_map(to_of_node(child), 0); if (fwnode_property_read_u32(child, "linux,code", &button->code)) { dev_err(dev, "Button without keycode\n"); fwnode_handle_put(child); return ERR_PTR(-EINVAL); } fwnode_property_read_string(child, "label", &button->desc); if (fwnode_property_read_u32(child, "linux,input-type", &button->type)) button->type = EV_KEY; button->wakeup = fwnode_property_read_bool(child, "wakeup-source") || /* legacy name */ fwnode_property_read_bool(child, "gpio-key,wakeup"); button->can_disable = fwnode_property_read_bool(child, "linux,can-disable"); if (fwnode_property_read_u32(child, "debounce-interval", &button->debounce_interval)) button->debounce_interval = 5; button++; } return pdata; }
static int xhci_plat_probe(struct platform_device *pdev) { const struct of_device_id *match; const struct hc_driver *driver; struct xhci_hcd *xhci; struct resource *res; struct usb_hcd *hcd; struct clk *clk; int ret; int irq; if (usb_disabled()) return -ENODEV; driver = &xhci_plat_hc_driver; irq = platform_get_irq(pdev, 0); if (irq < 0) return -ENODEV; /* Try to set 64-bit DMA first */ if (WARN_ON(!pdev->dev.dma_mask)) /* Platform did not initialize dma_mask */ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); else ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); /* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */ if (ret) { ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (ret) return ret; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); /* * Not all platforms have a clk so it is not an error if the * clock does not exists. */ clk = devm_clk_get(&pdev->dev, NULL); if (!IS_ERR(clk)) { ret = clk_prepare_enable(clk); if (ret) goto put_hcd; } else if (PTR_ERR(clk) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto put_hcd; } xhci = hcd_to_xhci(hcd); match = of_match_node(usb_xhci_of_match, pdev->dev.of_node); if (match) { const struct xhci_plat_priv *priv_match = match->data; struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); /* Just copy data for now */ if (priv_match) *priv = *priv_match; } device_wakeup_enable(hcd->self.controller); xhci->clk = clk; xhci->main_hcd = hcd; xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev, dev_name(&pdev->dev), hcd); if (!xhci->shared_hcd) { ret = -ENOMEM; goto disable_clk; } if (device_property_read_bool(&pdev->dev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; if (HCC_MAX_PSA(xhci->hcc_params) >= 4) xhci->shared_hcd->can_do_streams = 1; hcd->usb_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); if (IS_ERR(hcd->usb_phy)) { ret = PTR_ERR(hcd->usb_phy); if (ret == -EPROBE_DEFER) goto put_usb3_hcd; hcd->usb_phy = NULL; } else { ret = usb_phy_init(hcd->usb_phy); if (ret) goto put_usb3_hcd; } ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto disable_usb_phy; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (ret) goto dealloc_usb2_hcd; return 0; dealloc_usb2_hcd: usb_remove_hcd(hcd); disable_usb_phy: usb_phy_shutdown(hcd->usb_phy); put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); disable_clk: if (!IS_ERR(clk)) clk_disable_unprepare(clk); put_hcd: usb_put_hcd(hcd); return ret; }
static int pimhyp3_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pimhyp3_ts_data *ts; int error; u8 buf; dev_dbg(&client->dev, "I2C Address: 0x%02x\n", client->addr); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C check functionality failed.\n"); return -ENXIO; } ts = devm_kzalloc(&client->dev, sizeof(*ts), GFP_KERNEL); if (!ts) return -ENOMEM; ts->client = client; i2c_set_clientdata(client, ts); error = pimhyp3_i2c_test(client); if (error) { dev_err(&client->dev, "I2C communication failure: %d\n", error); return error; } //Device is detected! pr_info("Detected: pimhyp3"); if (device_property_read_bool(&ts->client->dev,"touchscreen-check")) { //We have notified the device is fitted, but we don't want to use it pr_info("Device check only. Exiting pimhyp3"); return -EBUSY; } pimhyp3_get_gpio_config(ts); if (ts->use_poll) buf = 0b00001110; //En_Int, Int_POLL, INT_MODE1, INT_MODE2 else buf = 0b00001100; //En_Int, Int_POLL, INT_MODE1, INT_MODE2 //For polling, use 00001110 //for interrupt use 00001100 pimhyp3_i2c_write(client, PIMHYP3_INT_SETTINGS, &buf,1); lcd_init(ts); pimhyp3_request_input_dev(ts); dev_dbg(&client->dev, "Cypress cy8c20466 driver installed\n"); if (ts->use_poll) { /* create thread that polls the touch events */ dev_dbg( &ts->client->dev, "Setting up POLL thread"); ts->thread = kthread_run(pimhyp3_thread, ts, "cy82466?"); if (ts->thread == NULL) { dev_err(&client->dev, "Failed to create kernel thread"); error = -ENOMEM; return error; } } else { /* Enable Interrupt to handle touch events */ dev_dbg( &ts->client->dev, "Setting up IRQ"); ts->irq_flags = pimhyp3_irq_flags[ts->int_trigger_type] | IRQF_ONESHOT; error = pimhyp3_request_irq(ts); if (error) { dev_err(&ts->client->dev, "request IRQ failed: %d\n", error); return error; } } pr_info("Using: pimhyp3"); return 0; }
/** * pimhyp3_get_gpio_config - Get GPIO config from ACPI/DT * * @ts: pimhyp3_ts_data pointer */ static int pimhyp3_get_gpio_config(struct pimhyp3_ts_data *ts) { int error; struct device *dev; struct gpio_desc *gpiod; u32 sizeX, sizeY, refreshRate; if (!ts->client) return -EINVAL; dev = &ts->client->dev; /* Get the interrupt GPIO pin description */ gpiod = devm_gpiod_get(dev, PIMHYP3_GPIO_INT_NAME, GPIOD_IN); if (IS_ERR(gpiod)) { error = PTR_ERR(gpiod); if (error != -EPROBE_DEFER) dev_dbg(dev, "Failed to get %s GPIO: %d\n", PIMHYP3_GPIO_INT_NAME, error); return error; } /* Ensure the correct direction is set because this pin is also used to * program the LCD controller */ ts->gpiod_int = gpiod; gpiod_direction_input(ts->gpiod_int); /* Get the MOSI GPIO pin description */ gpiod = devm_gpiod_get(dev, PIMHYP3_GPIO_MOSI_NAME, GPIOD_OUT_LOW); if (IS_ERR(gpiod)) { error = PTR_ERR(gpiod); if (error != -EPROBE_DEFER) dev_dbg(dev, "Failed to get %s GPIO: %d\n", PIMHYP3_GPIO_MOSI_NAME, error); return error; } ts->gpiod_mosi = gpiod; /* Get the CS GPIO pin description */ gpiod = devm_gpiod_get(dev, PIMHYP3_GPIO_CS_NAME, GPIOD_OUT_HIGH); if (IS_ERR(gpiod)) { error = PTR_ERR(gpiod); if (error != -EPROBE_DEFER) dev_dbg(dev, "Failed to get %s GPIO: %d\n", PIMHYP3_GPIO_CS_NAME, error); return error; } ts->gpiod_cs = gpiod; ts->id = 0x1001; ts->version=0x0101; ts->last_numTouches=0; ts->max_touch_num=2; ts->abs_x_max = PIMHYP3_MAX_WIDTH; ts->abs_y_max = PIMHYP3_MAX_HEIGHT; ts->use_poll = false; ts->int_trigger_type = PIMHYP3_INT_TRIGGER; // Read DT configuration parameters ts->X2Y = device_property_read_bool(&ts->client->dev, "touchscreen-x2y"); dev_dbg(&ts->client->dev, "touchscreen-x2y %u", ts->X2Y); ts->use_poll = device_property_read_bool(&ts->client->dev, "touchscreen-poll"); dev_dbg(&ts->client->dev, "touchscreen-poll %u", ts->use_poll); if(device_property_read_u32(&ts->client->dev, "touchscreen-refresh-rate", &refreshRate)) { dev_dbg(&ts->client->dev, "touchscreen-refresh-rate not found"); ts->requestedRefreshRate = 17; } else { dev_dbg(&ts->client->dev, "touchscreen-refresh-rate found %u", refreshRate); ts->requestedRefreshRate = (u8)refreshRate; } if(device_property_read_u32(&ts->client->dev, "touchscreen-size-x", &sizeX)) { dev_dbg(&ts->client->dev, "touchscreen-size-x not found. Using default of %u",ts->abs_x_max); } else { ts->abs_x_max = (u16)sizeX; dev_dbg(&ts->client->dev, "touchscreen-size-x found %u", ts->abs_x_max); } if(device_property_read_u32(&ts->client->dev, "touchscreen-size-y", &sizeY)) { dev_dbg(&ts->client->dev, "touchscreen-size-y not found. Using default of %u",ts->abs_y_max); } else { ts->abs_y_max = (u16)sizeY; dev_dbg(&ts->client->dev, "touchscreen-size-y found %u", ts->abs_y_max); } dev_dbg(&ts->client->dev, "requested size (%u, %u)", ts->abs_x_max, ts->abs_y_max); ts->swapped_x_y = device_property_read_bool(&ts->client->dev, "touchscreen-swapped-x-y"); dev_dbg(&ts->client->dev, "touchscreen-swapped-x-y %u", ts->swapped_x_y); ts->inverted_x = device_property_read_bool(&ts->client->dev, "touchscreen-inverted-x"); dev_dbg(&ts->client->dev, "touchscreen-inverted-x %u", ts->inverted_x); ts->inverted_y = device_property_read_bool(&ts->client->dev, "touchscreen-inverted-y"); dev_dbg(&ts->client->dev, "touchscreen-inverted-y %u", ts->inverted_y); return 0; }
/** * touchscreen_parse_properties - parse common touchscreen DT properties * @input: input device that should be parsed * @multitouch: specifies whether parsed properties should be applied to * single-touch or multi-touch axes * @prop: pointer to a struct touchscreen_properties into which to store * axis swap and invert info for use with touchscreen_report_x_y(); * or %NULL * * This function parses common DT properties for touchscreens and setups the * input device accordingly. The function keeps previously set up default * values if no value is specified via DT. */ void touchscreen_parse_properties(struct input_dev *input, bool multitouch, struct touchscreen_properties *prop) { struct device *dev = input->dev.parent; unsigned int axis; unsigned int maximum, fuzz; bool data_present; input_alloc_absinfo(input); if (!input->absinfo) return; axis = multitouch ? ABS_MT_POSITION_X : ABS_X; data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-x", input_abs_get_max(input, axis) + 1, &maximum) | touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x", input_abs_get_fuzz(input, axis), &fuzz); if (data_present) touchscreen_set_params(input, axis, maximum - 1, fuzz); axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y; data_present = touchscreen_get_prop_u32(dev, "touchscreen-size-y", input_abs_get_max(input, axis) + 1, &maximum) | touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y", input_abs_get_fuzz(input, axis), &fuzz); if (data_present) touchscreen_set_params(input, axis, maximum - 1, fuzz); axis = multitouch ? ABS_MT_PRESSURE : ABS_PRESSURE; data_present = touchscreen_get_prop_u32(dev, "touchscreen-max-pressure", input_abs_get_max(input, axis), &maximum) | touchscreen_get_prop_u32(dev, "touchscreen-fuzz-pressure", input_abs_get_fuzz(input, axis), &fuzz); if (data_present) touchscreen_set_params(input, axis, maximum, fuzz); if (!prop) return; axis = multitouch ? ABS_MT_POSITION_X : ABS_X; prop->max_x = input_abs_get_max(input, axis); prop->max_y = input_abs_get_max(input, axis + 1); prop->invert_x = device_property_read_bool(dev, "touchscreen-inverted-x"); prop->invert_y = device_property_read_bool(dev, "touchscreen-inverted-y"); prop->swap_x_y = device_property_read_bool(dev, "touchscreen-swapped-x-y"); if (prop->swap_x_y) swap(input->absinfo[axis], input->absinfo[axis + 1]); }
static int xhci_plat_probe(struct platform_device *pdev) { const struct xhci_plat_priv *priv_match; const struct hc_driver *driver; struct device *sysdev; struct xhci_hcd *xhci; struct resource *res; struct usb_hcd *hcd; struct clk *clk; int ret; int irq; if (usb_disabled()) return -ENODEV; driver = &xhci_plat_hc_driver; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; /* * sysdev must point to a device that is known to the system firmware * or PCI hardware. We handle these three cases here: * 1. xhci_plat comes from firmware * 2. xhci_plat is child of a device from firmware (dwc3-plat) * 3. xhci_plat is grandchild of a pci device (dwc3-pci) */ for (sysdev = &pdev->dev; sysdev; sysdev = sysdev->parent) { if (is_of_node(sysdev->fwnode) || is_acpi_device_node(sysdev->fwnode)) break; #ifdef CONFIG_PCI else if (sysdev->bus == &pci_bus_type) break; #endif } if (!sysdev) sysdev = &pdev->dev; /* Try to set 64-bit DMA first */ if (WARN_ON(!sysdev->dma_mask)) /* Platform did not initialize dma_mask */ ret = dma_coerce_mask_and_coherent(sysdev, DMA_BIT_MASK(64)); else ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(64)); /* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */ if (ret) { ret = dma_set_mask_and_coherent(sysdev, DMA_BIT_MASK(32)); if (ret) return ret; } pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, dev_name(&pdev->dev), NULL); if (!hcd) { ret = -ENOMEM; goto disable_runtime; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); hcd->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(hcd->regs)) { ret = PTR_ERR(hcd->regs); goto put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); /* * Not all platforms have a clk so it is not an error if the * clock does not exists. */ clk = devm_clk_get(&pdev->dev, NULL); if (!IS_ERR(clk)) { ret = clk_prepare_enable(clk); if (ret) goto put_hcd; } else if (PTR_ERR(clk) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto put_hcd; } xhci = hcd_to_xhci(hcd); priv_match = of_device_get_match_data(&pdev->dev); if (priv_match) { struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); /* Just copy data for now */ if (priv_match) *priv = *priv_match; } device_wakeup_enable(hcd->self.controller); xhci->clk = clk; xhci->main_hcd = hcd; xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev, dev_name(&pdev->dev), hcd); if (!xhci->shared_hcd) { ret = -ENOMEM; goto disable_clk; } if (device_property_read_bool(sysdev, "usb2-lpm-disable")) xhci->quirks |= XHCI_HW_LPM_DISABLE; if (device_property_read_bool(sysdev, "usb3-lpm-capable")) xhci->quirks |= XHCI_LPM_SUPPORT; if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) xhci->quirks |= XHCI_BROKEN_PORT_PED; /* imod_interval is the interrupt moderation value in nanoseconds. */ xhci->imod_interval = 40000; device_property_read_u32(sysdev, "imod-interval-ns", &xhci->imod_interval); hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); if (IS_ERR(hcd->usb_phy)) { ret = PTR_ERR(hcd->usb_phy); if (ret == -EPROBE_DEFER) goto put_usb3_hcd; hcd->usb_phy = NULL; } else { ret = usb_phy_init(hcd->usb_phy); if (ret) goto put_usb3_hcd; } ret = usb_add_hcd(hcd, irq, IRQF_SHARED); if (ret) goto disable_usb_phy; if (HCC_MAX_PSA(xhci->hcc_params) >= 4) xhci->shared_hcd->can_do_streams = 1; ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED); if (ret) goto dealloc_usb2_hcd; device_enable_async_suspend(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); /* * Prevent runtime pm from being on as default, users should enable * runtime pm using power/control in sysfs. */ pm_runtime_forbid(&pdev->dev); return 0; dealloc_usb2_hcd: usb_remove_hcd(hcd); disable_usb_phy: usb_phy_shutdown(hcd->usb_phy); put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); disable_clk: if (!IS_ERR(clk)) clk_disable_unprepare(clk); put_hcd: usb_put_hcd(hcd); disable_runtime: pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; }
static void dwc3_core_setup_global_control(struct dwc3 *dwc) { u32 hwparams4 = dwc->hwparams.hwparams4; u32 reg; reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) { case DWC3_GHWPARAMS1_EN_PWROPT_CLK: /** * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an * issue which would cause xHCI compliance tests to fail. * * Because of that we cannot enable clock gating on such * configurations. * * Refers to: * * STAR#9000588375: Clock Gating, SOF Issues when ref_clk-Based * SOF/ITP Mode Used */ if ((dwc->dr_mode == USB_DR_MODE_HOST || dwc->dr_mode == USB_DR_MODE_OTG) && (dwc->revision >= DWC3_REVISION_210A && dwc->revision <= DWC3_REVISION_250A)) reg |= DWC3_GCTL_DSBLCLKGTNG | DWC3_GCTL_SOFITPSYNC; else reg &= ~DWC3_GCTL_DSBLCLKGTNG; break; case DWC3_GHWPARAMS1_EN_PWROPT_HIB: if (!device_property_read_bool(dwc->dev, "snps,enable-hibernation")) { dev_dbg(dwc->dev, "Hibernation not enabled\n"); } else { /* enable hibernation here */ dwc->nr_scratch = DWC3_GHWPARAMS4_HIBER_SCRATCHBUFS(hwparams4); dwc->has_hibernation = 1; } /* * REVISIT Enabling this bit so that host-mode hibernation * will work. Device-mode hibernation is not yet implemented. */ reg |= DWC3_GCTL_GBLHIBERNATIONEN; break; default: /* nothing */ break; } /* check if current dwc3 is on simulation board */ if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) { dev_info(dwc->dev, "Running with FPGA optmizations\n"); dwc->is_fpga = true; } WARN_ONCE(dwc->disable_scramble_quirk && !dwc->is_fpga, "disable_scramble cannot be used on non-FPGA builds\n"); if (dwc->disable_scramble_quirk && dwc->is_fpga) reg |= DWC3_GCTL_DISSCRAMBLE; else reg &= ~DWC3_GCTL_DISSCRAMBLE; if (dwc->u2exit_lfps_quirk) reg |= DWC3_GCTL_U2EXIT_LFPS; /* * WORKAROUND: DWC3 revisions <1.90a have a bug * where the device can fail to connect at SuperSpeed * and falls back to high-speed mode which causes * the device to enter a Connect/Disconnect loop */ if (dwc->revision < DWC3_REVISION_190A) reg |= DWC3_GCTL_U2RSTECN; dwc3_writel(dwc->regs, DWC3_GCTL, reg); }
static int rotary_encoder_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rotary_encoder *encoder; struct input_dev *input; irq_handler_t handler; u32 steps_per_period; unsigned int i; int err; encoder = devm_kzalloc(dev, sizeof(struct rotary_encoder), GFP_KERNEL); if (!encoder) return -ENOMEM; mutex_init(&encoder->access_mutex); device_property_read_u32(dev, "rotary-encoder,steps", &encoder->steps); err = device_property_read_u32(dev, "rotary-encoder,steps-per-period", &steps_per_period); if (err) { /* * The 'half-period' property has been deprecated, you must * use 'steps-per-period' and set an appropriate value, but * we still need to parse it to maintain compatibility. If * neither property is present we fall back to the one step * per period behavior. */ steps_per_period = device_property_read_bool(dev, "rotary-encoder,half-period") ? 2 : 1; } encoder->rollover = device_property_read_bool(dev, "rotary-encoder,rollover"); if (!device_property_present(dev, "rotary-encoder,encoding") || !device_property_match_string(dev, "rotary-encoder,encoding", "gray")) { dev_info(dev, "gray"); encoder->encoding = ROTENC_GRAY; } else if (!device_property_match_string(dev, "rotary-encoder,encoding", "binary")) { dev_info(dev, "binary"); encoder->encoding = ROTENC_BINARY; } else { dev_err(dev, "unknown encoding setting\n"); return -EINVAL; } device_property_read_u32(dev, "linux,axis", &encoder->axis); encoder->relative_axis = device_property_read_bool(dev, "rotary-encoder,relative-axis"); encoder->gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN); if (IS_ERR(encoder->gpios)) { dev_err(dev, "unable to get gpios\n"); return PTR_ERR(encoder->gpios); } if (encoder->gpios->ndescs < 2) { dev_err(dev, "not enough gpios found\n"); return -EINVAL; } input = devm_input_allocate_device(dev); if (!input) return -ENOMEM; encoder->input = input; input->name = pdev->name; input->id.bustype = BUS_HOST; input->dev.parent = dev; if (encoder->relative_axis) input_set_capability(input, EV_REL, encoder->axis); else input_set_abs_params(input, encoder->axis, 0, encoder->steps, 0, 1); switch (steps_per_period >> (encoder->gpios->ndescs - 2)) { case 4: handler = &rotary_encoder_quarter_period_irq; encoder->last_stable = rotary_encoder_get_state(encoder); break; case 2: handler = &rotary_encoder_half_period_irq; encoder->last_stable = rotary_encoder_get_state(encoder); break; case 1: handler = &rotary_encoder_irq; break; default: dev_err(dev, "'%d' is not a valid steps-per-period value\n", steps_per_period); return -EINVAL; } encoder->irq = devm_kcalloc(dev, encoder->gpios->ndescs, sizeof(*encoder->irq), GFP_KERNEL); if (!encoder->irq) return -ENOMEM; for (i = 0; i < encoder->gpios->ndescs; ++i) { encoder->irq[i] = gpiod_to_irq(encoder->gpios->desc[i]); err = devm_request_threaded_irq(dev, encoder->irq[i], NULL, handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRV_NAME, encoder); if (err) { dev_err(dev, "unable to request IRQ %d (gpio#%d)\n", encoder->irq[i], i); return err; } } err = input_register_device(input); if (err) { dev_err(dev, "failed to register input device\n"); return err; } device_init_wakeup(dev, device_property_read_bool(dev, "wakeup-source")); platform_set_drvdata(pdev, encoder); return 0; }
static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct dwc3_platform_data *pdata = dev_get_platdata(dev); struct resource *res; struct dwc3 *dwc; u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; u32 fladj = 0; int ret; void __iomem *regs; void *mem; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); if (!mem) return -ENOMEM; dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; dwc->dev = dev; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "missing IRQ\n"); return -ENODEV; } dwc->xhci_resources[1].start = res->start; dwc->xhci_resources[1].end = res->end; dwc->xhci_resources[1].flags = res->flags; dwc->xhci_resources[1].name = res->name; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "missing memory resource\n"); return -ENODEV; } dwc->xhci_resources[0].start = res->start; dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + DWC3_XHCI_REGS_END; dwc->xhci_resources[0].flags = res->flags; dwc->xhci_resources[0].name = res->name; res->start += DWC3_GLOBALS_REGS_START; /* * Request memory region but exclude xHCI regs, * since it will be requested by the xhci-plat driver. */ regs = devm_ioremap_resource(dev, res); if (IS_ERR(regs)) { ret = PTR_ERR(regs); goto err0; } dwc->regs = regs; dwc->regs_size = resource_size(res); /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; /* default to -3.5dB de-emphasis */ tx_de_emphasis = 1; /* * default to assert utmi_sleep_n and use maximum allowed HIRD * threshold value of 0b1100 */ hird_threshold = 12; dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->dr_mode = usb_get_dr_mode(dev); dwc->has_lpm_erratum = device_property_read_bool(dev, "snps,has-lpm-erratum"); device_property_read_u8(dev, "snps,lpm-nyet-threshold", &lpm_nyet_threshold); dwc->is_utmi_l1_suspend = device_property_read_bool(dev, "snps,is-utmi-l1-suspend"); device_property_read_u8(dev, "snps,hird-threshold", &hird_threshold); dwc->usb3_lpm_capable = device_property_read_bool(dev, "snps,usb3_lpm_capable"); dwc->needs_fifo_resize = device_property_read_bool(dev, "tx-fifo-resize"); dwc->disable_scramble_quirk = device_property_read_bool(dev, "snps,disable_scramble_quirk"); dwc->u2exit_lfps_quirk = device_property_read_bool(dev, "snps,u2exit_lfps_quirk"); dwc->u2ss_inp3_quirk = device_property_read_bool(dev, "snps,u2ss_inp3_quirk"); dwc->req_p1p2p3_quirk = device_property_read_bool(dev, "snps,req_p1p2p3_quirk"); dwc->del_p1p2p3_quirk = device_property_read_bool(dev, "snps,del_p1p2p3_quirk"); dwc->del_phy_power_chg_quirk = device_property_read_bool(dev, "snps,del_phy_power_chg_quirk"); dwc->lfps_filter_quirk = device_property_read_bool(dev, "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = device_property_read_bool(dev, "snps,rx_detect_poll_quirk"); dwc->dis_u3_susphy_quirk = device_property_read_bool(dev, "snps,dis_u3_susphy_quirk"); dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, "snps,dis_u2_susphy_quirk"); dwc->dis_enblslpm_quirk = device_property_read_bool(dev, "snps,dis_enblslpm_quirk"); dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, "snps,tx_de_emphasis_quirk"); device_property_read_u8(dev, "snps,tx_de_emphasis", &tx_de_emphasis); device_property_read_string(dev, "snps,hsphy_interface", &dwc->hsphy_interface); device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", &fladj); if (pdata) { dwc->maximum_speed = pdata->maximum_speed; dwc->has_lpm_erratum = pdata->has_lpm_erratum; if (pdata->lpm_nyet_threshold) lpm_nyet_threshold = pdata->lpm_nyet_threshold; dwc->is_utmi_l1_suspend = pdata->is_utmi_l1_suspend; if (pdata->hird_threshold) hird_threshold = pdata->hird_threshold; dwc->needs_fifo_resize = pdata->tx_fifo_resize; dwc->usb3_lpm_capable = pdata->usb3_lpm_capable; dwc->dr_mode = pdata->dr_mode; dwc->disable_scramble_quirk = pdata->disable_scramble_quirk; dwc->u2exit_lfps_quirk = pdata->u2exit_lfps_quirk; dwc->u2ss_inp3_quirk = pdata->u2ss_inp3_quirk; dwc->req_p1p2p3_quirk = pdata->req_p1p2p3_quirk; dwc->del_p1p2p3_quirk = pdata->del_p1p2p3_quirk; dwc->del_phy_power_chg_quirk = pdata->del_phy_power_chg_quirk; dwc->lfps_filter_quirk = pdata->lfps_filter_quirk; dwc->rx_detect_poll_quirk = pdata->rx_detect_poll_quirk; dwc->dis_u3_susphy_quirk = pdata->dis_u3_susphy_quirk; dwc->dis_u2_susphy_quirk = pdata->dis_u2_susphy_quirk; dwc->dis_enblslpm_quirk = pdata->dis_enblslpm_quirk; dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk; if (pdata->tx_de_emphasis) tx_de_emphasis = pdata->tx_de_emphasis; dwc->hsphy_interface = pdata->hsphy_interface; fladj = pdata->fladj_value; } dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); platform_set_drvdata(pdev, dwc); dwc3_cache_hwparams(dwc); ret = dwc3_phy_setup(dwc); if (ret) goto err0; ret = dwc3_core_get_phy(dwc); if (ret) goto err0; spin_lock_init(&dwc->lock); if (!dev->dma_mask) { dev->dma_mask = dev->parent->dma_mask; dev->dma_parms = dev->parent->dma_parms; dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask); } pm_runtime_enable(dev); pm_runtime_get_sync(dev); pm_runtime_forbid(dev); ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); ret = -ENOMEM; goto err1; } if (IS_ENABLED(CONFIG_USB_DWC3_HOST)) dwc->dr_mode = USB_DR_MODE_HOST; else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET)) dwc->dr_mode = USB_DR_MODE_PERIPHERAL; if (dwc->dr_mode == USB_DR_MODE_UNKNOWN) dwc->dr_mode = USB_DR_MODE_OTG; ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); goto err1; } /* Check the maximum_speed parameter */ switch (dwc->maximum_speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_SUPER: case USB_SPEED_SUPER_PLUS: break; default: dev_err(dev, "invalid maximum_speed parameter %d\n", dwc->maximum_speed); /* fall through */ case USB_SPEED_UNKNOWN: /* default to superspeed */ dwc->maximum_speed = USB_SPEED_SUPER; /* * default to superspeed plus if we are capable. */ if (dwc3_is_usb31(dwc) && (DWC3_GHWPARAMS3_SSPHY_IFC(dwc->hwparams.hwparams3) == DWC3_GHWPARAMS3_SSPHY_IFC_GEN2)) dwc->maximum_speed = USB_SPEED_SUPER_PLUS; break; } /* Adjust Frame Length */ dwc3_frame_length_adjustment(dwc, fladj); usb_phy_set_suspend(dwc->usb2_phy, 0); usb_phy_set_suspend(dwc->usb3_phy, 0); ret = phy_power_on(dwc->usb2_generic_phy); if (ret < 0) goto err2; ret = phy_power_on(dwc->usb3_generic_phy); if (ret < 0) goto err3; ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); goto err4; } ret = dwc3_core_init_mode(dwc); if (ret) goto err5; ret = dwc3_debugfs_init(dwc); if (ret) { dev_err(dev, "failed to initialize debugfs\n"); goto err6; } pm_runtime_allow(dev); return 0; err6: dwc3_core_exit_mode(dwc); err5: dwc3_event_buffers_cleanup(dwc); err4: phy_power_off(dwc->usb3_generic_phy); err3: phy_power_off(dwc->usb2_generic_phy); err2: usb_phy_set_suspend(dwc->usb2_phy, 1); usb_phy_set_suspend(dwc->usb3_phy, 1); dwc3_core_exit(dwc); err1: dwc3_free_event_buffers(dwc); dwc3_ulpi_exit(dwc); err0: /* * restore res->start back to its original value so that, in case the * probe is deferred, we don't end up getting error in request the * memory region the next time probe is called. */ res->start -= DWC3_GLOBALS_REGS_START; return ret; }
static void dwc3_get_properties(struct dwc3 *dwc) { struct device *dev = dwc->dev; u8 lpm_nyet_threshold; u8 tx_de_emphasis; u8 hird_threshold; /* default to highest possible threshold */ lpm_nyet_threshold = 0xff; /* default to -3.5dB de-emphasis */ tx_de_emphasis = 1; /* * default to assert utmi_sleep_n and use maximum allowed HIRD * threshold value of 0b1100 */ hird_threshold = 12; dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->dr_mode = usb_get_dr_mode(dev); dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node); dwc->sysdev_is_parent = device_property_read_bool(dev, "linux,sysdev_is_parent"); if (dwc->sysdev_is_parent) dwc->sysdev = dwc->dev->parent; else dwc->sysdev = dwc->dev; dwc->has_lpm_erratum = device_property_read_bool(dev, "snps,has-lpm-erratum"); device_property_read_u8(dev, "snps,lpm-nyet-threshold", &lpm_nyet_threshold); dwc->is_utmi_l1_suspend = device_property_read_bool(dev, "snps,is-utmi-l1-suspend"); device_property_read_u8(dev, "snps,hird-threshold", &hird_threshold); dwc->usb3_lpm_capable = device_property_read_bool(dev, "snps,usb3_lpm_capable"); dwc->disable_scramble_quirk = device_property_read_bool(dev, "snps,disable_scramble_quirk"); dwc->u2exit_lfps_quirk = device_property_read_bool(dev, "snps,u2exit_lfps_quirk"); dwc->u2ss_inp3_quirk = device_property_read_bool(dev, "snps,u2ss_inp3_quirk"); dwc->req_p1p2p3_quirk = device_property_read_bool(dev, "snps,req_p1p2p3_quirk"); dwc->del_p1p2p3_quirk = device_property_read_bool(dev, "snps,del_p1p2p3_quirk"); dwc->del_phy_power_chg_quirk = device_property_read_bool(dev, "snps,del_phy_power_chg_quirk"); dwc->lfps_filter_quirk = device_property_read_bool(dev, "snps,lfps_filter_quirk"); dwc->rx_detect_poll_quirk = device_property_read_bool(dev, "snps,rx_detect_poll_quirk"); dwc->dis_u3_susphy_quirk = device_property_read_bool(dev, "snps,dis_u3_susphy_quirk"); dwc->dis_u2_susphy_quirk = device_property_read_bool(dev, "snps,dis_u2_susphy_quirk"); dwc->dis_enblslpm_quirk = device_property_read_bool(dev, "snps,dis_enblslpm_quirk"); dwc->dis_rxdet_inp3_quirk = device_property_read_bool(dev, "snps,dis_rxdet_inp3_quirk"); dwc->dis_u2_freeclk_exists_quirk = device_property_read_bool(dev, "snps,dis-u2-freeclk-exists-quirk"); dwc->dis_del_phy_power_chg_quirk = device_property_read_bool(dev, "snps,dis-del-phy-power-chg-quirk"); dwc->tx_de_emphasis_quirk = device_property_read_bool(dev, "snps,tx_de_emphasis_quirk"); device_property_read_u8(dev, "snps,tx_de_emphasis", &tx_de_emphasis); device_property_read_string(dev, "snps,hsphy_interface", &dwc->hsphy_interface); device_property_read_u32(dev, "snps,quirk-frame-length-adjustment", &dwc->fladj); dwc->lpm_nyet_threshold = lpm_nyet_threshold; dwc->tx_de_emphasis = tx_de_emphasis; dwc->hird_threshold = hird_threshold | (dwc->is_utmi_l1_suspend << 4); dwc->imod_interval = 0; }
static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); int irq = platform_get_irq(pdev, 0); struct uart_port *p = &uart.port; struct dw8250_data *data; int err; u32 val; if (!regs) { dev_err(&pdev->dev, "no registers defined\n"); return -EINVAL; } if (irq < 0) { if (irq != -EPROBE_DEFER) dev_err(&pdev->dev, "cannot get irq\n"); return irq; } spin_lock_init(&p->lock); p->mapbase = regs->start; p->irq = irq; p->handle_irq = dw8250_handle_irq; p->pm = dw8250_do_pm; p->type = PORT_8250; p->flags = UPF_SHARE_IRQ | UPF_FIXED_PORT; p->dev = &pdev->dev; p->iotype = UPIO_MEM; p->serial_in = dw8250_serial_in; p->serial_out = dw8250_serial_out; p->membase = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!p->membase) return -ENOMEM; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; data->dma.fn = dw8250_fallback_dma_filter; data->usr_reg = DW_UART_USR; p->private_data = data; data->uart_16550_compatible = device_property_read_bool(p->dev, "snps,uart-16550-compatible"); err = device_property_read_u32(p->dev, "reg-shift", &val); if (!err) p->regshift = val; err = device_property_read_u32(p->dev, "reg-io-width", &val); if (!err && val == 4) { p->iotype = UPIO_MEM32; p->serial_in = dw8250_serial_in32; p->serial_out = dw8250_serial_out32; } if (device_property_read_bool(p->dev, "dcd-override")) { /* Always report DCD as active */ data->msr_mask_on |= UART_MSR_DCD; data->msr_mask_off |= UART_MSR_DDCD; } if (device_property_read_bool(p->dev, "dsr-override")) { /* Always report DSR as active */ data->msr_mask_on |= UART_MSR_DSR; data->msr_mask_off |= UART_MSR_DDSR; } if (device_property_read_bool(p->dev, "cts-override")) { /* Always report CTS as active */ data->msr_mask_on |= UART_MSR_CTS; data->msr_mask_off |= UART_MSR_DCTS; } if (device_property_read_bool(p->dev, "ri-override")) { /* Always report Ring indicator as inactive */ data->msr_mask_off |= UART_MSR_RI; data->msr_mask_off |= UART_MSR_TERI; } /* Always ask for fixed clock rate from a property. */ device_property_read_u32(p->dev, "clock-frequency", &p->uartclk); /* If there is separate baudclk, get the rate from it. */ data->clk = devm_clk_get(&pdev->dev, "baudclk"); if (IS_ERR(data->clk) && PTR_ERR(data->clk) != -EPROBE_DEFER) data->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) return -EPROBE_DEFER; if (!IS_ERR_OR_NULL(data->clk)) { err = clk_prepare_enable(data->clk); if (err) dev_warn(&pdev->dev, "could not enable optional baudclk: %d\n", err); else p->uartclk = clk_get_rate(data->clk); } /* If no clock rate is defined, fail. */ if (!p->uartclk) { dev_err(&pdev->dev, "clock rate not defined\n"); return -EINVAL; } data->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_clk; } if (!IS_ERR(data->pclk)) { err = clk_prepare_enable(data->pclk); if (err) { dev_err(&pdev->dev, "could not enable apb_pclk\n"); goto err_clk; } } data->rst = devm_reset_control_get_optional(&pdev->dev, NULL); if (IS_ERR(data->rst) && PTR_ERR(data->rst) == -EPROBE_DEFER) { err = -EPROBE_DEFER; goto err_pclk; } if (!IS_ERR(data->rst)) reset_control_deassert(data->rst); dw8250_quirks(p, data); /* If the Busy Functionality is not implemented, don't handle it */ if (data->uart_16550_compatible) p->handle_irq = NULL; if (!data->skip_autocfg) dw8250_setup_port(p); /* If we have a valid fifosize, try hooking up DMA */ if (p->fifosize) { data->dma.rxconf.src_maxburst = p->fifosize / 4; data->dma.txconf.dst_maxburst = p->fifosize / 4; uart.dma = &data->dma; } data->line = serial8250_register_8250_port(&uart); if (data->line < 0) { err = data->line; goto err_reset; } platform_set_drvdata(pdev, data); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); return 0; err_reset: if (!IS_ERR(data->rst)) reset_control_assert(data->rst); err_pclk: if (!IS_ERR(data->pclk)) clk_disable_unprepare(data->pclk); err_clk: if (!IS_ERR(data->clk)) clk_disable_unprepare(data->clk); return err; }