// SPDX-License-Identifier: GPL-2.0+
/*
* R-Car Gen3 Digital Radio Interface (DRIF) driver
*
* Copyright (C) 2017 Renesas Electronics Corporation
*/
/*
* The R-Car DRIF is a receive only MSIOF like controller with an
* external master device driving the SCK. It receives data into a FIFO,
* then this driver uses the SYS-DMAC engine to move the data from
* the device to memory.
*
* Each DRIF channel DRIFx (as per datasheet) contains two internal
* channels DRIFx0 & DRIFx1 within itself with each having its own resources
* like module clk, register set, irq and dma. These internal channels share
* common CLK & SYNC from master. The two data pins D0 & D1 shall be
* considered to represent the two internal channels. This internal split
* is not visible to the master device.
*
* Depending on the master device, a DRIF channel can use
* (1) both internal channels (D0 & D1) to receive data in parallel (or)
* (2) one internal channel (D0 or D1) to receive data
*
* The primary design goal of this controller is to act as a Digital Radio
* Interface that receives digital samples from a tuner device. Hence the
* driver exposes the device as a V4L2 SDR device. In order to qualify as
* a V4L2 SDR device, it should possess a tuner interface as mandated by the
* framework. This driver expects a tuner driver (sub-device) to bind
* asynchronously with this device and the combined drivers shall expose
* a V4L2 compliant SDR device. The DRIF driver is independent of the
* tuner vendor.
*
* The DRIF h/w can support I2S mode and Frame start synchronization pulse mode.
* This driver is tested for I2S mode only because of the availability of
* suitable master devices. Hence, not all configurable options of DRIF h/w
* like lsb/msb first, syncdl, dtdl etc. are exposed via DT and I2S defaults
* are used. These can be exposed later if needed after testing.
*/
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/ioctl.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>
/* DRIF register offsets */
#define RCAR_DRIF_SITMDR1 0x00
#define RCAR_