375 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Copyright (C) 2017-2020 Jacopo Mondi4 * Copyright (C) 2017-2020 Kieran Bingham5 * Copyright (C) 2017-2020 Laurent Pinchart6 * Copyright (C) 2017-2020 Niklas Söderlund7 * Copyright (C) 2016 Renesas Electronics Corporation8 * Copyright (C) 2015 Cogent Embedded, Inc.9 *10 * This file exports functions to control the Maxim MAX9271 GMSL serializer11 * chip. This is not a self-contained driver, as MAX9271 is usually embedded in12 * camera modules with at least one image sensor and optional additional13 * components, such as uController units or ISPs/DSPs.14 *15 * Drivers for the camera modules (i.e. rdacm20/21) are expected to use16 * functions exported from this library driver to maximize code re-use.17 */18 19#include <linux/delay.h>20#include <linux/i2c.h>21#include <linux/module.h>22 23#include "max9271.h"24 25static int max9271_read(struct max9271_device *dev, u8 reg)26{27 int ret;28 29 dev_dbg(&dev->client->dev, "%s(0x%02x)\n", __func__, reg);30 31 ret = i2c_smbus_read_byte_data(dev->client, reg);32 if (ret < 0)33 dev_dbg(&dev->client->dev,34 "%s: register 0x%02x read failed (%d)\n",35 __func__, reg, ret);36 37 return ret;38}39 40static int max9271_write(struct max9271_device *dev, u8 reg, u8 val)41{42 int ret;43 44 dev_dbg(&dev->client->dev, "%s(0x%02x, 0x%02x)\n", __func__, reg, val);45 46 ret = i2c_smbus_write_byte_data(dev->client, reg, val);47 if (ret < 0)48 dev_err(&dev->client->dev,49 "%s: register 0x%02x write failed (%d)\n",50 __func__, reg, ret);51 52 return ret;53}54 55/*56 * max9271_pclk_detect() - Detect valid pixel clock from image sensor57 *58 * Wait up to 10ms for a valid pixel clock.59 *60 * Returns 0 for success, < 0 for pixel clock not properly detected61 */62static int max9271_pclk_detect(struct max9271_device *dev)63{64 unsigned int i;65 int ret;66 67 for (i = 0; i < 100; i++) {68 ret = max9271_read(dev, 0x15);69 if (ret < 0)70 return ret;71 72 if (ret & MAX9271_PCLKDET)73 return 0;74 75 usleep_range(50, 100);76 }77 78 dev_err(&dev->client->dev, "Unable to detect valid pixel clock\n");79 80 return -EIO;81}82 83void max9271_wake_up(struct max9271_device *dev)84{85 /*86 * Use the chip default address as this function has to be called87 * before any other one.88 */89 dev->client->addr = MAX9271_DEFAULT_ADDR;90 i2c_smbus_read_byte(dev->client);91 usleep_range(5000, 8000);92}93EXPORT_SYMBOL_GPL(max9271_wake_up);94 95int max9271_set_serial_link(struct max9271_device *dev, bool enable)96{97 int ret;98 u8 val = MAX9271_REVCCEN | MAX9271_FWDCCEN;99 100 if (enable) {101 ret = max9271_pclk_detect(dev);102 if (ret)103 return ret;104 105 val |= MAX9271_SEREN;106 } else {107 val |= MAX9271_CLINKEN;108 }109 110 /*111 * The serializer temporarily disables the reverse control channel for112 * 350µs after starting/stopping the forward serial link, but the113 * deserializer synchronization time isn't clearly documented.114 *115 * According to the serializer datasheet we should wait 3ms, while116 * according to the deserializer datasheet we should wait 5ms.117 *118 * Short delays here appear to show bit-errors in the writes following.119 * Therefore a conservative delay seems best here.120 */121 ret = max9271_write(dev, 0x04, val);122 if (ret < 0)123 return ret;124 125 usleep_range(5000, 8000);126 127 return 0;128}129EXPORT_SYMBOL_GPL(max9271_set_serial_link);130 131int max9271_configure_i2c(struct max9271_device *dev, u8 i2c_config)132{133 int ret;134 135 ret = max9271_write(dev, 0x0d, i2c_config);136 if (ret < 0)137 return ret;138 139 /* The delay required after an I2C bus configuration change is not140 * characterized in the serializer manual. Sleep up to 5msec to141 * stay safe.142 */143 usleep_range(3500, 5000);144 145 return 0;146}147EXPORT_SYMBOL_GPL(max9271_configure_i2c);148 149int max9271_set_high_threshold(struct max9271_device *dev, bool enable)150{151 int ret;152 153 ret = max9271_read(dev, 0x08);154 if (ret < 0)155 return ret;156 157 /*158 * Enable or disable reverse channel high threshold to increase159 * immunity to power supply noise.160 */161 ret = max9271_write(dev, 0x08, enable ? ret | BIT(0) : ret & ~BIT(0));162 if (ret < 0)163 return ret;164 165 usleep_range(2000, 2500);166 167 return 0;168}169EXPORT_SYMBOL_GPL(max9271_set_high_threshold);170 171int max9271_configure_gmsl_link(struct max9271_device *dev)172{173 int ret;174 175 /*176 * Configure the GMSL link:177 *178 * - Double input mode, high data rate, 24-bit mode179 * - Latch input data on PCLKIN rising edge180 * - Enable HS/VS encoding181 * - 1-bit parity error detection182 *183 * TODO: Make the GMSL link configuration parametric.184 */185 ret = max9271_write(dev, 0x07, MAX9271_DBL | MAX9271_HVEN |186 MAX9271_EDC_1BIT_PARITY);187 if (ret < 0)188 return ret;189 190 usleep_range(5000, 8000);191 192 /*193 * Adjust spread spectrum to +4% and auto-detect pixel clock194 * and serial link rate.195 */196 ret = max9271_write(dev, 0x02,197 MAX9271_SPREAD_SPECT_4 | MAX9271_R02_RES |198 MAX9271_PCLK_AUTODETECT |199 MAX9271_SERIAL_AUTODETECT);200 if (ret < 0)201 return ret;202 203 usleep_range(5000, 8000);204 205 return 0;206}207EXPORT_SYMBOL_GPL(max9271_configure_gmsl_link);208 209int max9271_set_gpios(struct max9271_device *dev, u8 gpio_mask)210{211 int ret;212 213 ret = max9271_read(dev, 0x0f);214 if (ret < 0)215 return 0;216 217 ret |= gpio_mask;218 ret = max9271_write(dev, 0x0f, ret);219 if (ret < 0) {220 dev_err(&dev->client->dev, "Failed to set gpio (%d)\n", ret);221 return ret;222 }223 224 usleep_range(3500, 5000);225 226 return 0;227}228EXPORT_SYMBOL_GPL(max9271_set_gpios);229 230int max9271_clear_gpios(struct max9271_device *dev, u8 gpio_mask)231{232 int ret;233 234 ret = max9271_read(dev, 0x0f);235 if (ret < 0)236 return 0;237 238 ret &= ~gpio_mask;239 ret = max9271_write(dev, 0x0f, ret);240 if (ret < 0) {241 dev_err(&dev->client->dev, "Failed to clear gpio (%d)\n", ret);242 return ret;243 }244 245 usleep_range(3500, 5000);246 247 return 0;248}249EXPORT_SYMBOL_GPL(max9271_clear_gpios);250 251int max9271_enable_gpios(struct max9271_device *dev, u8 gpio_mask)252{253 int ret;254 255 ret = max9271_read(dev, 0x0e);256 if (ret < 0)257 return 0;258 259 /* BIT(0) reserved: GPO is always enabled. */260 ret |= (gpio_mask & ~BIT(0));261 ret = max9271_write(dev, 0x0e, ret);262 if (ret < 0) {263 dev_err(&dev->client->dev, "Failed to enable gpio (%d)\n", ret);264 return ret;265 }266 267 usleep_range(3500, 5000);268 269 return 0;270}271EXPORT_SYMBOL_GPL(max9271_enable_gpios);272 273int max9271_disable_gpios(struct max9271_device *dev, u8 gpio_mask)274{275 int ret;276 277 ret = max9271_read(dev, 0x0e);278 if (ret < 0)279 return 0;280 281 /* BIT(0) reserved: GPO cannot be disabled */282 ret &= ~(gpio_mask | BIT(0));283 ret = max9271_write(dev, 0x0e, ret);284 if (ret < 0) {285 dev_err(&dev->client->dev, "Failed to disable gpio (%d)\n", ret);286 return ret;287 }288 289 usleep_range(3500, 5000);290 291 return 0;292}293EXPORT_SYMBOL_GPL(max9271_disable_gpios);294 295int max9271_verify_id(struct max9271_device *dev)296{297 int ret;298 299 ret = max9271_read(dev, 0x1e);300 if (ret < 0) {301 dev_err(&dev->client->dev, "MAX9271 ID read failed (%d)\n",302 ret);303 return ret;304 }305 306 if (ret != MAX9271_ID) {307 dev_err(&dev->client->dev, "MAX9271 ID mismatch (0x%02x)\n",308 ret);309 return -ENXIO;310 }311 312 return 0;313}314EXPORT_SYMBOL_GPL(max9271_verify_id);315 316int max9271_set_address(struct max9271_device *dev, u8 addr)317{318 int ret;319 320 ret = max9271_write(dev, 0x00, addr << 1);321 if (ret < 0) {322 dev_err(&dev->client->dev,323 "MAX9271 I2C address change failed (%d)\n", ret);324 return ret;325 }326 usleep_range(3500, 5000);327 328 return 0;329}330EXPORT_SYMBOL_GPL(max9271_set_address);331 332int max9271_set_deserializer_address(struct max9271_device *dev, u8 addr)333{334 int ret;335 336 ret = max9271_write(dev, 0x01, addr << 1);337 if (ret < 0) {338 dev_err(&dev->client->dev,339 "MAX9271 deserializer address set failed (%d)\n", ret);340 return ret;341 }342 usleep_range(3500, 5000);343 344 return 0;345}346EXPORT_SYMBOL_GPL(max9271_set_deserializer_address);347 348int max9271_set_translation(struct max9271_device *dev, u8 source, u8 dest)349{350 int ret;351 352 ret = max9271_write(dev, 0x09, source << 1);353 if (ret < 0) {354 dev_err(&dev->client->dev,355 "MAX9271 I2C translation setup failed (%d)\n", ret);356 return ret;357 }358 usleep_range(3500, 5000);359 360 ret = max9271_write(dev, 0x0a, dest << 1);361 if (ret < 0) {362 dev_err(&dev->client->dev,363 "MAX9271 I2C translation setup failed (%d)\n", ret);364 return ret;365 }366 usleep_range(3500, 5000);367 368 return 0;369}370EXPORT_SYMBOL_GPL(max9271_set_translation);371 372MODULE_DESCRIPTION("Maxim MAX9271 GMSL Serializer");373MODULE_AUTHOR("Jacopo Mondi");374MODULE_LICENSE("GPL v2");375