cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

max9271.c (8226B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Copyright (C) 2017-2020 Jacopo Mondi
      4 * Copyright (C) 2017-2020 Kieran Bingham
      5 * Copyright (C) 2017-2020 Laurent Pinchart
      6 * Copyright (C) 2017-2020 Niklas Söderlund
      7 * Copyright (C) 2016 Renesas Electronics Corporation
      8 * Copyright (C) 2015 Cogent Embedded, Inc.
      9 *
     10 * This file exports functions to control the Maxim MAX9271 GMSL serializer
     11 * chip. This is not a self-contained driver, as MAX9271 is usually embedded in
     12 * camera modules with at least one image sensor and optional additional
     13 * components, such as uController units or ISPs/DSPs.
     14 *
     15 * Drivers for the camera modules (i.e. rdacm20/21) are expected to use
     16 * 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 sensor
     57 *
     58 * Wait up to 10ms for a valid pixel clock.
     59 *
     60 * Returns 0 for success, < 0 for pixel clock not properly detected
     61 */
     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 called
     87	 * 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 for
    112	 * 350µs after starting/stopping the forward serial link, but the
    113	 * deserializer synchronization time isn't clearly documented.
    114	 *
    115	 * According to the serializer datasheet we should wait 3ms, while
    116	 * 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 not
    140	 * characterized in the serializer manual. Sleep up to 5msec to
    141	 * 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 increase
    159	 * 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 mode
    179	 * - Latch input data on PCLKIN rising edge
    180	 * - Enable HS/VS encoding
    181	 * - 1-bit parity error detection
    182	 *
    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 clock
    194	 * 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");