コード例 #1
0
ファイル: btmrvl_main.c プロジェクト: AK101111/linux
static int btmrvl_check_device_tree(struct btmrvl_private *priv)
{
	struct device_node *dt_node;
	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
	u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
	int ret = 0;
	u16 gpio, gap;

	if (card->plt_of_node) {
		dt_node = card->plt_of_node;
		ret = of_property_read_u16(dt_node, "marvell,wakeup-pin",
					   &gpio);
		if (ret)
			gpio = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;

		ret = of_property_read_u16(dt_node, "marvell,wakeup-gap-ms",
					   &gap);
		if (ret)
			gap = (u8)(priv->btmrvl_dev.gpio_gap & 0x00ff);

		priv->btmrvl_dev.gpio_gap = (gpio << 8) + gap;

		ret = of_property_read_u8_array(dt_node, "marvell,cal-data",
						cal_data + BT_CAL_HDR_LEN,
						BT_CAL_DATA_SIZE);
		if (ret)
			return ret;

		BT_DBG("Use cal data from device tree");
		ret = btmrvl_download_cal_data(priv, cal_data,
					       BT_CAL_DATA_SIZE);
		if (ret)
			BT_ERR("Fail to download calibrate data");
	}
コード例 #2
0
static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x)
{
    struct device_node *np = dev->of_node;
    struct sta32x_platform_data *pdata;
    u16 tmp;

    pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
    if (!pdata)
        return -ENOMEM;

    of_property_read_u8(np, "st,output-conf",
                        &pdata->output_conf);
    of_property_read_u8(np, "st,ch1-output-mapping",
                        &pdata->ch1_output_mapping);
    of_property_read_u8(np, "st,ch2-output-mapping",
                        &pdata->ch2_output_mapping);
    of_property_read_u8(np, "st,ch3-output-mapping",
                        &pdata->ch3_output_mapping);

    if (of_get_property(np, "st,thermal-warning-recovery", NULL))
        pdata->thermal_warning_recovery = 1;
    if (of_get_property(np, "st,thermal-warning-adjustment", NULL))
        pdata->thermal_warning_adjustment = 1;
    if (of_get_property(np, "st,needs_esd_watchdog", NULL))
        pdata->needs_esd_watchdog = 1;

    tmp = 140;
    of_property_read_u16(np, "st,drop-compensation-ns", &tmp);
    pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;

    /* CONFE */
    if (of_get_property(np, "st,max-power-use-mpcc", NULL))
        pdata->max_power_use_mpcc = 1;

    if (of_get_property(np, "st,max-power-correction", NULL))
        pdata->max_power_correction = 1;

    if (of_get_property(np, "st,am-reduction-mode", NULL))
        pdata->am_reduction_mode = 1;

    if (of_get_property(np, "st,odd-pwm-speed-mode", NULL))
        pdata->odd_pwm_speed_mode = 1;

    /* CONFF */
    if (of_get_property(np, "st,invalid-input-detect-mute", NULL))
        pdata->invalid_input_detect_mute = 1;

    sta32x->pdata = pdata;

    return 0;
}
コード例 #3
0
int get_hw_config_u16(const char *node_name,
        const char *prop_name, u16 *pvalue)
{
    struct device_node *np;
    int ret;

    if(node_name == NULL ||
        prop_name == NULL ||
        pvalue == NULL) {
        hwlog_err("Invalid Argument, NULL passed\n");
        return -EINVAL;
    }

    np = of_find_node_by_name(NULL, node_name);
    if (!np) {
        hwlog_err("can not get device node with node_name: %s\n", node_name);
        return -ENODEV;
    }

    if(0 == is_property_public(np, prop_name)) {
        hwlog_err("property to read is not public, permission denied\n");
        ret = -EACCES;
        goto OUT;
    }

    ret = of_property_read_u16(np, prop_name, pvalue);
    if (ret != 0) {
        hwlog_err("can not get prop values with prop_name: %s\n", prop_name);
        goto OUT;
    }

OUT:
    of_node_put(np);

    return ret;
}
コード例 #4
0
ファイル: sta350.c プロジェクト: Seagate/SMR_FS-EXT4
static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350)
{
	struct device_node *np = dev->of_node;
	struct sta350_platform_data *pdata;
	const char *ffx_power_mode;
	u16 tmp;
	u8 tmp8;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	of_property_read_u8(np, "st,output-conf",
			    &pdata->output_conf);
	of_property_read_u8(np, "st,ch1-output-mapping",
			    &pdata->ch1_output_mapping);
	of_property_read_u8(np, "st,ch2-output-mapping",
			    &pdata->ch2_output_mapping);
	of_property_read_u8(np, "st,ch3-output-mapping",
			    &pdata->ch3_output_mapping);

	if (of_get_property(np, "st,thermal-warning-recovery", NULL))
		pdata->thermal_warning_recovery = 1;
	if (of_get_property(np, "st,thermal-warning-adjustment", NULL))
		pdata->thermal_warning_adjustment = 1;
	if (of_get_property(np, "st,fault-detect-recovery", NULL))
		pdata->fault_detect_recovery = 1;

	pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP;
	if (!of_property_read_string(np, "st,ffx-power-output-mode",
				     &ffx_power_mode)) {
		int i, mode = -EINVAL;

		for (i = 0; i < ARRAY_SIZE(sta350_ffx_modes); i++)
			if (!strcasecmp(ffx_power_mode, sta350_ffx_modes[i]))
				mode = i;

		if (mode < 0)
			dev_warn(dev, "Unsupported ffx output mode: %s\n",
				 ffx_power_mode);
		else
			pdata->ffx_power_output_mode = mode;
	}

	tmp = 140;
	of_property_read_u16(np, "st,drop-compensation-ns", &tmp);
	pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;

	if (of_get_property(np, "st,overcurrent-warning-adjustment", NULL))
		pdata->oc_warning_adjustment = 1;

	/* CONFE */
	if (of_get_property(np, "st,max-power-use-mpcc", NULL))
		pdata->max_power_use_mpcc = 1;

	if (of_get_property(np, "st,max-power-correction", NULL))
		pdata->max_power_correction = 1;

	if (of_get_property(np, "st,am-reduction-mode", NULL))
		pdata->am_reduction_mode = 1;

	if (of_get_property(np, "st,odd-pwm-speed-mode", NULL))
		pdata->odd_pwm_speed_mode = 1;

	if (of_get_property(np, "st,distortion-compensation", NULL))
		pdata->distortion_compensation = 1;

	/* CONFF */
	if (of_get_property(np, "st,invalid-input-detect-mute", NULL))
		pdata->invalid_input_detect_mute = 1;

	/* MISC */
	if (of_get_property(np, "st,activate-mute-output", NULL))
		pdata->activate_mute_output = 1;

	if (of_get_property(np, "st,bridge-immediate-off", NULL))
		pdata->bridge_immediate_off = 1;

	if (of_get_property(np, "st,noise-shape-dc-cut", NULL))
		pdata->noise_shape_dc_cut = 1;

	if (of_get_property(np, "st,powerdown-master-volume", NULL))
		pdata->powerdown_master_vol = 1;

	if (!of_property_read_u8(np, "st,powerdown-delay-divider", &tmp8)) {
		if (is_power_of_2(tmp8) && tmp8 >= 1 && tmp8 <= 128)
			pdata->powerdown_delay_divider = ilog2(tmp8);
		else
			dev_warn(dev, "Unsupported powerdown delay divider %d\n",
				 tmp8);
	}

	sta350->pdata = pdata;

	return 0;
}
コード例 #5
0
ファイル: spi-qup.c プロジェクト: 3null/linux
static int spi_qup_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct clk *iclk, *cclk;
	struct spi_qup *controller;
	struct resource *res;
	struct device *dev;
	void __iomem *base;
	u32 max_freq, iomode;
	int ret, irq, size;

	dev = &pdev->dev;
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	cclk = devm_clk_get(dev, "core");
	if (IS_ERR(cclk))
		return PTR_ERR(cclk);

	iclk = devm_clk_get(dev, "iface");
	if (IS_ERR(iclk))
		return PTR_ERR(iclk);

	/* This is optional parameter */
	if (of_property_read_u32(dev->of_node, "spi-max-frequency", &max_freq))
		max_freq = SPI_MAX_RATE;

	if (!max_freq || max_freq > SPI_MAX_RATE) {
		dev_err(dev, "invalid clock frequency %d\n", max_freq);
		return -ENXIO;
	}

	ret = clk_prepare_enable(cclk);
	if (ret) {
		dev_err(dev, "cannot enable core clock\n");
		return ret;
	}

	ret = clk_prepare_enable(iclk);
	if (ret) {
		clk_disable_unprepare(cclk);
		dev_err(dev, "cannot enable iface clock\n");
		return ret;
	}

	master = spi_alloc_master(dev, sizeof(struct spi_qup));
	if (!master) {
		clk_disable_unprepare(cclk);
		clk_disable_unprepare(iclk);
		dev_err(dev, "cannot allocate master\n");
		return -ENOMEM;
	}

	/* use num-cs unless not present or out of range */
	if (of_property_read_u16(dev->of_node, "num-cs",
			&master->num_chipselect) ||
			(master->num_chipselect > SPI_NUM_CHIPSELECTS))
		master->num_chipselect = SPI_NUM_CHIPSELECTS;

	master->bus_num = pdev->id;
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
	master->max_speed_hz = max_freq;
	master->transfer_one = spi_qup_transfer_one;
	master->dev.of_node = pdev->dev.of_node;
	master->auto_runtime_pm = true;

	platform_set_drvdata(pdev, master);

	controller = spi_master_get_devdata(master);

	controller->dev = dev;
	controller->base = base;
	controller->iclk = iclk;
	controller->cclk = cclk;
	controller->irq = irq;

	/* set v1 flag if device is version 1 */
	if (of_device_is_compatible(dev->of_node, "qcom,spi-qup-v1.1.1"))
		controller->qup_v1 = 1;

	spin_lock_init(&controller->lock);
	init_completion(&controller->done);

	iomode = readl_relaxed(base + QUP_IO_M_MODES);

	size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode);
	if (size)
		controller->out_blk_sz = size * 16;
	else
		controller->out_blk_sz = 4;

	size = QUP_IO_M_INPUT_BLOCK_SIZE(iomode);
	if (size)
		controller->in_blk_sz = size * 16;
	else
		controller->in_blk_sz = 4;

	size = QUP_IO_M_OUTPUT_FIFO_SIZE(iomode);
	controller->out_fifo_sz = controller->out_blk_sz * (2 << size);

	size = QUP_IO_M_INPUT_FIFO_SIZE(iomode);
	controller->in_fifo_sz = controller->in_blk_sz * (2 << size);

	dev_info(dev, "IN:block:%d, fifo:%d, OUT:block:%d, fifo:%d\n",
		 controller->in_blk_sz, controller->in_fifo_sz,
		 controller->out_blk_sz, controller->out_fifo_sz);

	writel_relaxed(1, base + QUP_SW_RESET);

	ret = spi_qup_set_state(controller, QUP_STATE_RESET);
	if (ret) {
		dev_err(dev, "cannot set RESET state\n");
		goto error;
	}

	writel_relaxed(0, base + QUP_OPERATIONAL);
	writel_relaxed(0, base + QUP_IO_M_MODES);

	if (!controller->qup_v1)
		writel_relaxed(0, base + QUP_OPERATIONAL_MASK);

	writel_relaxed(SPI_ERROR_CLK_UNDER_RUN | SPI_ERROR_CLK_OVER_RUN,
		       base + SPI_ERROR_FLAGS_EN);

	/* if earlier version of the QUP, disable INPUT_OVERRUN */
	if (controller->qup_v1)
		writel_relaxed(QUP_ERROR_OUTPUT_OVER_RUN |
			QUP_ERROR_INPUT_UNDER_RUN | QUP_ERROR_OUTPUT_UNDER_RUN,
			base + QUP_ERROR_FLAGS_EN);

	writel_relaxed(0, base + SPI_CONFIG);
	writel_relaxed(SPI_IO_C_NO_TRI_STATE, base + SPI_IO_CONTROL);

	ret = devm_request_irq(dev, irq, spi_qup_qup_irq,
			       IRQF_TRIGGER_HIGH, pdev->name, controller);
	if (ret)
		goto error;

	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	ret = devm_spi_register_master(dev, master);
	if (ret)
		goto disable_pm;

	return 0;

disable_pm:
	pm_runtime_disable(&pdev->dev);
error:
	clk_disable_unprepare(cclk);
	clk_disable_unprepare(iclk);
	spi_master_put(master);
	return ret;
}