/* * @Author: HuYaosong * @Date: 2022-07-21 15:40:48 * @LastEditors: HuYaosong * @LastEditTime: 2022-07-22 16:15:14 * @Description: * * Copyright (c) 2022 by vanjee, All Rights Reserved. */ #include #include #include #include #include #include #include struct max96705 { struct i2c_client *i2c_client; struct regmap *regmap; struct mutex lock; }; static int max96705_write_reg(struct device *dev, u16 addr, u8 val) { struct max96705 *priv; int err, retry; priv = dev_get_drvdata(dev); for(retry = 0; retry < 10; retry++) { err = regmap_write(priv->regmap, addr, val); if (!err) break; dev_err(dev, "%s:i2c write failed, 0x%x = %x,retry=%d\n", __func__, addr, val,retry); usleep_range(100, 110); } usleep_range(200, 210); return err; } int max96705_setup(struct device *dev) { max96705_write_reg(dev, 0x67, 0xC4); msleep(5); max96705_write_reg(dev, 0x07, 0x84); /* set cross bar */ max96705_write_reg(dev, 0x20, 0x02); max96705_write_reg(dev, 0x21, 0x03); max96705_write_reg(dev, 0x22, 0x04); max96705_write_reg(dev, 0x23, 0x05); max96705_write_reg(dev, 0x24, 0x06); max96705_write_reg(dev, 0x25, 0x07); max96705_write_reg(dev, 0x26, 0x08); max96705_write_reg(dev, 0x27, 0x09); max96705_write_reg(dev, 0x30, 0x12); max96705_write_reg(dev, 0x31, 0x13); max96705_write_reg(dev, 0x32, 0x14); max96705_write_reg(dev, 0x33, 0x15); max96705_write_reg(dev, 0x34, 0x16); max96705_write_reg(dev, 0x35, 0x17); max96705_write_reg(dev, 0x36, 0x18); max96705_write_reg(dev, 0x37, 0x19); return 0; } EXPORT_SYMBOL(max96705_setup); const struct of_device_id max96705_of_match[] = { { .compatible = "maxim,max96705-wj", }, { }, }; static struct regmap_config max96705_regmap_config = { .reg_bits = 8, .val_bits = 8, .cache_type = REGCACHE_RBTREE, }; static int max96705_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct max96705 *priv; int err = 0; dev_info(&client->dev, "[MAX96705-wj]: probing GMSL Serializer\n"); priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); if (priv == NULL) { dev_err(&client->dev, "no memory\n"); return -ENOMEM; } priv->i2c_client = client; priv->regmap = devm_regmap_init_i2c(priv->i2c_client, &max96705_regmap_config); if (IS_ERR(priv->regmap)) { dev_err(&client->dev, "regmap init failed: %ld\n", PTR_ERR(priv->regmap)); return -ENODEV; } mutex_init(&priv->lock); dev_set_drvdata(&client->dev, priv); /* dev communication gets validated when GMSL link setup is done */ dev_info(&client->dev, "%s: success\n", __func__); return err; } static int max96705_remove(struct i2c_client *client) { struct max96705 *priv; if (client != NULL) { priv = dev_get_drvdata(&client->dev); mutex_destroy(&priv->lock); i2c_unregister_device(client); client = NULL; } return 0; } static const struct i2c_device_id max96705_id[] = { { "max96705", 0 }, { }, }; MODULE_DEVICE_TABLE(i2c, max96705_id); static struct i2c_driver max96705_i2c_driver = { .driver = { .name = "max96705", .owner = THIS_MODULE, .of_match_table = of_match_ptr(max96705_of_match), }, .probe = max96705_probe, .remove = max96705_remove, .id_table = max96705_id, }; static int __init max96705_init(void) { return i2c_add_driver(&max96705_i2c_driver); } static void __exit max96705_exit(void) { i2c_del_driver(&max96705_i2c_driver); } module_init(max96705_init); module_exit(max96705_exit); MODULE_DESCRIPTION("GMSL serializer driver max96705 work with TZ026V02"); MODULE_AUTHOR("huyaosong@wanji.net.cn"); MODULE_LICENSE("GPL v2");