ret = i2c_transfer(i2c->adapter, xfer, 2); if (ret < 0) return ret; if (ret != 2) return -EIO;
/* * Byte 0 is transfer length, which is always 1 due * to BCP register programming to 1 in rs9_probe(), * ignore it and use data from Byte 1.
*/
*val = rxdata[1]; return 0;
}
static u8 rs9_calc_dif(conststruct rs9_driver_data *rs9, int idx)
{ /* * On 9FGV0241, the DIF OE0 is BIT(1) and DIF OE(1) is BIT(2), * on 9FGV0441 and 9FGV0841 the DIF OE0 is BIT(0) and so on. * Increment the index in the 9FGV0241 special case here.
*/ return BIT(idx + rs9->chip_info->outshift);
}
staticvoid rs9_update_config(struct rs9_driver_data *rs9)
{ int i;
/* If amplitude is non-default, update it. */ if (rs9->pll_amplitude != RS9_REG_SS_AMP_DEFAULT) {
regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_AMP_MASK,
rs9->pll_amplitude);
}
/* If SSC is non-default, update it. */ if (rs9->pll_ssc != RS9_REG_SS_SSC_DEFAULT) {
regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_SSC_MASK,
rs9->pll_ssc);
}
for (i = 0; i < rs9->chip_info->num_clks; i++) {
u8 dif = rs9_calc_dif(rs9, i);
/* Fetch common configuration from DT (if specified) */
ret = rs9_get_common_config(rs9); if (ret) return ret;
/* Fetch DIFx output configuration from DT (if specified) */ for (i = 0; i < rs9->chip_info->num_clks; i++) {
ret = rs9_get_output_config(rs9, i); if (ret) return ret;
}
rs9->regmap = devm_regmap_init(&client->dev, NULL,
client, &rs9_regmap_config); if (IS_ERR(rs9->regmap)) return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap), "Failed to allocate register map\n");
/* Always read back 1 Byte via I2C */
ret = regmap_write(rs9->regmap, RS9_REG_BCP, 1); if (ret < 0) return ret;
ret = regmap_read(rs9->regmap, RS9_REG_VID, &vid); if (ret < 0) return ret;
ret = regmap_read(rs9->regmap, RS9_REG_DID, &did); if (ret < 0) return ret;
vid &= RS9_REG_VID_MASK; if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did) return dev_err_probe(&client->dev, -ENODEV, "Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n",
vid, did, RS9_REG_VID_IDT,
rs9->chip_info->did);
/* Register clock */ for (i = 0; i < rs9->chip_info->num_clks; i++) {
snprintf(name, 5, "DIF%d", i);
hw = devm_clk_hw_register_fixed_factor_index(&client->dev, name,
0, 0, 4, 1); if (IS_ERR(hw)) return PTR_ERR(hw);
rs9->clk_dif[i] = hw;
}
ret = devm_of_clk_add_hw_provider(&client->dev, rs9_of_clk_get, rs9); if (!ret)
rs9_update_config(rs9);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.