From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755150AbeARIpV (ORCPT ); Thu, 18 Jan 2018 03:45:21 -0500 Received: from mail-sn1nam01on0092.outbound.protection.outlook.com ([104.47.32.92]:1377 "EHLO NAM01-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754870AbeARIpH (ORCPT ); Thu, 18 Jan 2018 03:45:07 -0500 From: To: , , CC: , , , , , , , Subject: [PATCH v5 04/12] [media] cxd2880: Add spi device IO routines Date: Thu, 18 Jan 2018 17:48:58 +0900 Message-ID: <20180118084858.21151-1-Yasunari.Takiguchi@sony.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180118084016.20689-1-Yasunari.Takiguchi@sony.com> References: <20180118084016.20689-1-Yasunari.Takiguchi@sony.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [43.25.41.74] X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-HT: Tenant X-Forefront-Antispam-Report: CIP:117.103.190.42;IPV:NLI;CTRY:JP;EFV:NLI;SFV:NSPM;SFS:(10019020)(39380400002)(39860400002)(346002)(376002)(396003)(2980300002)(438002)(199004)(189003)(51416003)(50226002)(6116002)(7636002)(7736002)(4326008)(246002)(8676002)(305945005)(8936002)(356003)(2906002)(66066001)(478600001)(2876002)(47776003)(76176011)(2950100002)(1076002)(3846002)(72206003)(6346003)(50466002)(956003)(59450400001)(36756003)(26005)(110136005)(54906003)(16526018)(5660300001)(106002)(2201001)(16586007)(86362001)(575784001)(107886003)(316002)(49486002)(106466001)(39060400002)(86152003)(48376002);DIR:OUT;SFP:1102;SCL:1;SRVR:MWHPR1301MB2032;H:jp.sony.com;FPR:;SPF:Pass;PTR:jpyokxeg102.jp.sony.com;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;CY1NAM02FT054;1:Q+8t84Uap82cDyjuWgql37qrvccQHacmbxkcCQ2zqLCybGbOBe7VNSjo5+7Hzzplv7cRFe76Wklp2Zyj4NXPSS55gxpS68vgOxmurOYVjkKSVRcKMdy/oY5M03jqrWYF X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 461f1f9c-2073-43b6-8eda-08d55e4fc55c X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652020)(4534125)(4602075)(4627221)(201703031133081)(201702281549075)(5600026)(4604075)(4608076)(2017052603307)(7193020);SRVR:MWHPR1301MB2032; X-Microsoft-Exchange-Diagnostics: 1;MWHPR1301MB2032;3:QPhOJ8tYISGVnQ78cn6IsiHUGGpSrfVQGXaH3QW7fEeTkdC+03DcHp121gsqWbZy5Tr0h3gy7iJmuSB3CSUiveUBMrwScO2j9SxMNMZbe6x04oGtwpZrlVbqeEjorjOrupc8RrhdTyg1PRafStxsNj0wEKVHp31Tm1JQaw0wU64fm73njx+Afo1U8/z2O57IlQdcjEs1vDpHYC9axLkeuZCght/SrqLMGJMuts0zU2ygygXvEhU4N2mr5/URXZh0SPPULnuoYhslHMyCcwrGUuG9xNx9CxImpz3HqbGm40azII9QnVBQyskn3+4rEquk7bneAfqOdjtXZ09kafBFrO2NiJ9FKfl+6YJalO3hAZA=;25:kDAF9/d8zGlL/GWbgStTfJr5F5Twb+xQ6tWdgVN2eogZC0GNBZgZ6fCDD0GCNKbHV/PN6ygmKxJLmejA0WW+4Hzk9UasrTPaJVACuinFaLA1RNpdTYPgYpGi4WW1ZxZHLN0HmSJQdukxZ0kP1BdKhLX2oZHpkIEhsv3tsBrH3HPAJIGVTDMhE8NvQRPrm4PN6U5TL1PDHpODcn5yNfsuxfJfh98ovbYkEA9BJCO/6TYtpLRMU6oMmq0V/JZZdEsdZ5RA0qAyMuGZ3kfActR9/vdESxNd2J0CEj+wQh06KxPkHLXaxiTUGiaGEubDhgkXKUlhdl4OLJkYBKbOfhzqyQ== X-MS-TrafficTypeDiagnostic: MWHPR1301MB2032: X-Microsoft-Exchange-Diagnostics: 1;MWHPR1301MB2032;31:InYA6Bv/6yjY/16Yc9KQW4jO0+0ArC7t8VYQ1FoKLI23HnMt1p3Q6baugF39EH/0NBihaAdoY7qEg/68HmQWpLjPTnnDwPnI3zpQhZDnUIyIiGF9oko3ni67eno4CLqr0xR8KwY/LBluMOlVa0TfjIvq9TCnjezGF2AcFPOUQxH4U3UtjPhjvvDEWGisTTShVfv6DEnLUWHW8m4jGKKGy7axkswsA5ntCgxukOSqthY=;20:R7YQJT9AazMk+NkwHF7tqyLoHk4qHImS15OucEd72on3yG6V7qN2rH2v+rpPeFqFm7eOq7n6laOfvaFrQw/H46djWdj1BtP2gc4XYV/Z4/HCkHkb7E8TYcmWWy4fOSr2/O7UfpZNJWc0a8fgjFOyOBNv8AlFI3w4XC8fHSlIU1bxt3nmzDVz/Tgc7X8JvdMQa8IkoDkD0o+rY6DNXKE0cd/PGPuFYvgPdtiE15Vat/+f9JL3/CqlsAnVzOwctPQkWpPvxlldKNNgI0NxTvVOduMYrSuLnV34Ytnj+Z+JPUDXr1edpNwL3ePIPCQSRdOsdpNmEOtkeuUQJv+n4IPMumgb3NTy0S/jPGK2ye8pYMO1sL7l7r/zjDqcWHaVVe0DlD16se8XIzfRkiRwAgl06dCx8nJThGucnieiY4ZOylYbN1mOuNj6PnW8DIl5iMmQI/TNRa+GzJeXk7OQ43Rbzil62EbSX5yd8OIjJN/IDGnfkDJevYoP5h1oPl7NgL5r X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(182409339516656); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040492)(2401047)(5005006)(8121501046)(3002001)(93006095)(93004095)(3231046)(11241501184)(2400058)(944501161)(10201501046)(6055026)(6041279)(20161123562045)(20161123564045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(6072148)(201708071742011);SRVR:MWHPR1301MB2032;BCL:0;PCL:0;RULEID:(100000803126)(100110400120);SRVR:MWHPR1301MB2032; X-Microsoft-Exchange-Diagnostics: 1;MWHPR1301MB2032;4:exFGyOFhk0UijOmsDeYzWe1aOmQLydprZEBq6ZJpzNT5JTMzI8XcH32hz2bGKoc8mHSAcFKwTsG4bJO0+LqFK9l4V2CR/jBkL9rl82XJeBO+1tuHdjChnUFP4QxooJavQyE35tkQV6lp6l4/OtjzfoaGUMJUTzp7zfNJ4uigICEpIPKKez338c73LxhiZBWFDZUs7AOKO7KGgNkMhAa8XMyr1zbLMzZjQIOdjjUyEw1Cjmkr0NRptd6vROrGZRmXANM+c390rTZyCWsYTpUQDANSCrQRmYh8Vznu7s4obLkYUBXnyoluFy0BatYdyCTg X-Forefront-PRVS: 05568D1FF7 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;MWHPR1301MB2032;23:WULgaLlpfdeudXbAb7+57iBDwnHFG4QA+wrMRNR?= =?us-ascii?Q?RoLF9rWLF7hwqwVZykAoX3KpJAQVZHqKGp7w/P1H2vd1NDwXGMytuPGvZBwI?= =?us-ascii?Q?ZCOAY+27iMlm47U13IKeQ0lCZsOARRCDcNy/qHsqy01JAwTA/xn5qF72PZP1?= =?us-ascii?Q?HuDBMfaRC93+3cw87zvGiDlpV8Av3L4beDBIykb67pVRmDMlVRHF2HYAWwi+?= =?us-ascii?Q?keCBAKzxCGXVc5Bd93G40CxI1+L0Z8/lK+kqj+RCydcPtL+1rzi2AC3iiSos?= =?us-ascii?Q?RsauVdQQ+/Q0FTJ646SSptyqwBHXWvGi70/DgeE05lTygQcYThDLK2rSDC4V?= =?us-ascii?Q?Dq9m4DDJumNhjGmZWvzKf15WQT05Hw56MS7Q40WdiLQANsXw6Qo+lqkkXmgB?= =?us-ascii?Q?uRJAtqvqeitjZDzuw5GuUtNrX0hD94Loy3gRj3hqI8rdTAlQj62siIjuN861?= =?us-ascii?Q?hWn/HG7Tz9WWBhiUaATHqAID+CDV7Girpl6PEbrocyj37v3GJJqmXiJOwFs2?= =?us-ascii?Q?y8s5J+coLL0Lc1I4xl7/jVxawCyUPwTQHaunGdCUTpeqBZxbUrErYO+lYciF?= =?us-ascii?Q?c2HFzOtvn5JqSKWWTbQUfKXcuUf4h/WFAZ5O5yk9Mhnm5nwdAPZOWH8eI+2p?= =?us-ascii?Q?aUCTxNyMI2LmS0np6rQaJNA3MLKQz63N3Mt64W6GgZqo/jry0zwsvrxDgkWH?= =?us-ascii?Q?8Ac2FJk+qDawyXa7AcZj6b7Q7fi/+Sg5MCDZzxFijFr6ZD6rwO1iPUpM6Mte?= =?us-ascii?Q?dbcSFw/3UFm7hzGScDfpvZ85cYMXVxSG/6Pzb00/19je0gyJf9NM/SdemuAA?= =?us-ascii?Q?CK2Lu09Cv8FUSG3zZtf7OnXXJpee93QeNxsr3JkwKTJzw8qt1Z1Vl5vPZwE2?= =?us-ascii?Q?TwL7jl0mbCu9V8cPdy+cMVBaUu1pk7uyRLcXHc+oy21sYhN9s5LQTaXIzl4J?= =?us-ascii?Q?rzrckVADqU8wFCon0L8sitA1elpOqCrEeyWULINcx9Eufw/gX3HNeKn6k2sa?= =?us-ascii?Q?6g7agw/VfNAYCtzP3+kPwmfWeKm9U1PuyeRoCrhlPtSwE3J7ch6UFppCBRfn?= =?us-ascii?Q?U4SVWYO6meJ0duTr8wsE0xBIBfjph45UWcEPA1X9+/mfZGSSrkIMUNdO6v8o?= =?us-ascii?Q?+SU3Q4Jr/OjbjNEtqNbNmkwfSU26pRKQiiNqOq70dgTWnD5gY8XBNWkhIYPF?= =?us-ascii?Q?dUdYDKxOCYJ9QklY=3D?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR1301MB2032;6:TwAi5I6L+qJ7wA1q3aRHoTIT2yjjLtGFhubj/V2jKUEYB+h8tPqsKgOVXoEghrIPITLGVoj7mzZqgJKxR7DpN0molxTW9fAy/7pUXjZ5F05eEXYRISU8eG0+pzHvzOlx5UW7N4yS8NI6WnSx2CpXdSExPU9yLAxm7BYROUZ6ZamlGrGIWGaDznJVP5wr2erjkhIiCy8n6e9S8e6tM+26txgjMTOH3chqQhFyVlEYVPmQP/NzI+g1DBJruP6pLW+6IkvAfmvPG8+KVjDH5frOM6dFOR+prA3of116U6K/6def0Fp12yHTi2cpMfStYFTXnIZBgKOyHIv+FIAdQ8XqSC08RrQN9ZrmpIBCY/ikQEs=;5:HDmaBOn17+pD84YWbVRvubNkJ/L4pvMmNhIzIwyoIRPXJkf9ScSY5AdXZV4oU+EYuhfw838uUMWkpfq17Q6mEJWo/a8bF82WEOP+PmgqpUedYn5kSOQ810mpnfjU26hX4HJAiI+eQHfSSGj2a/Xn6zlwWJcpo/KUK0p8xj06Jg0=;24:S41+wwxTs6jefibMRoOI6BelztusyIySl6ODyQyQpH4CqO84nbiCR2Er2Jqa3SYihqWmuFhx+MHNjyTvZLEFbhncVdR6Wz61EDToDvK8jlI=;7:1fHnA1gc5ak0OOleoRgBUPcsWcQBkWs8/oLXG02kjSlTzYY2R/M6pmnqXrlO8akD4oGKCvhf6jmxTKu5misJquH8oiBnOUahhKqX99gxQSSq0/k0KXhX0+Xz+jVmPFDdKydCWmy9hoJyspzVEHGwHl0EKW1JZvOqkHgEH+OHI5aPayCt0pHEwhA3/biVup8U+kBOU19AnAFAn3B/rFCLHK6HEZN/EoIycTNPvtFQhkiac7JUbL2s0RBw7IID0GhV SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: sony.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Jan 2018 08:45:04.4241 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 461f1f9c-2073-43b6-8eda-08d55e4fc55c X-MS-Exchange-CrossTenant-Id: 66c65d8a-9158-4521-a2d8-664963db48e4 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=66c65d8a-9158-4521-a2d8-664963db48e4;Ip=[117.103.190.42];Helo=[jp.sony.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR1301MB2032 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Yasunari Takiguchi Add functions for initializing, reading and writing to the SPI device for the Sony CXD2880 DVB-T2/T tuner + demodulator. Signed-off-by: Yasunari Takiguchi Signed-off-by: Masayuki Yamamoto Signed-off-by: Hideki Nozawa Signed-off-by: Kota Yonezawa Signed-off-by: Toshihiko Matsumoto Signed-off-by: Satoshi Watanabe --- [Change list] Changes in V5 Using SPDX-License-Identifier drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c -modified return error code -removed unnecessary parentheses drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c -removed unnecessary parentheses Changes in V4 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c -removed unnecessary initialization at variable declaration Changes in V3 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c -removed unnecessary cast -changed cxd2880_memcpy to memcpy -modified return code -changed hexadecimal code to lower case. drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h -modified return code drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h -modified return code drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c -removed unnecessary cast -modified return code drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h -modified return code .../dvb-frontends/cxd2880/cxd2880_devio_spi.c | 129 +++++++++++++++++++++ .../dvb-frontends/cxd2880/cxd2880_devio_spi.h | 23 ++++ drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h | 34 ++++++ .../dvb-frontends/cxd2880/cxd2880_spi_device.c | 113 ++++++++++++++++++ .../dvb-frontends/cxd2880/cxd2880_spi_device.h | 26 +++++ 5 files changed, 325 insertions(+) create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c new file mode 100644 index 000000000000..d2e37c95d748 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cxd2880_devio_spi.c + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * I/O interface via SPI + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#include "cxd2880_devio_spi.h" + +#define BURST_WRITE_MAX 128 + +static int cxd2880_io_spi_read_reg(struct cxd2880_io *io, + enum cxd2880_io_tgt tgt, + u8 sub_address, u8 *data, + u32 size) +{ + int ret; + struct cxd2880_spi *spi = NULL; + u8 send_data[6]; + u8 *read_data_top = data; + + if (!io || !io->if_object || !data) + return -EINVAL; + + if (sub_address + size > 0x100) + return -EINVAL; + + spi = io->if_object; + + if (tgt == CXD2880_IO_TGT_SYS) + send_data[0] = 0x0b; + else + send_data[0] = 0x0a; + + send_data[3] = 0; + send_data[4] = 0; + send_data[5] = 0; + + while (size > 0) { + send_data[1] = sub_address; + if (size > 255) + send_data[2] = 255; + else + send_data[2] = size; + + ret = + spi->write_read(spi, send_data, sizeof(send_data), + read_data_top, send_data[2]); + if (ret) + return ret; + + sub_address += send_data[2]; + read_data_top += send_data[2]; + size -= send_data[2]; + } + + return ret; +} + +static int cxd2880_io_spi_write_reg(struct cxd2880_io *io, + enum cxd2880_io_tgt tgt, + u8 sub_address, + const u8 *data, u32 size) +{ + int ret; + struct cxd2880_spi *spi = NULL; + u8 send_data[BURST_WRITE_MAX + 4]; + const u8 *write_data_top = data; + + if (!io || !io->if_object || !data) + return -EINVAL; + + if (size > BURST_WRITE_MAX) + return -EINVAL; + + if (sub_address + size > 0x100) + return -EINVAL; + + spi = io->if_object; + + if (tgt == CXD2880_IO_TGT_SYS) + send_data[0] = 0x0f; + else + send_data[0] = 0x0e; + + while (size > 0) { + send_data[1] = sub_address; + if (size > 255) + send_data[2] = 255; + else + send_data[2] = size; + + memcpy(&send_data[3], write_data_top, send_data[2]); + + if (tgt == CXD2880_IO_TGT_SYS) { + send_data[3 + send_data[2]] = 0x00; + ret = spi->write(spi, send_data, send_data[2] + 4); + } else { + ret = spi->write(spi, send_data, send_data[2] + 3); + } + if (ret) + return ret; + + sub_address += send_data[2]; + write_data_top += send_data[2]; + size -= send_data[2]; + } + + return ret; +} + +int cxd2880_io_spi_create(struct cxd2880_io *io, + struct cxd2880_spi *spi, u8 slave_select) +{ + if (!io || !spi) + return -EINVAL; + + io->read_regs = cxd2880_io_spi_read_reg; + io->write_regs = cxd2880_io_spi_write_reg; + io->write_reg = cxd2880_io_common_write_one_reg; + io->if_object = spi; + io->i2c_address_sys = 0; + io->i2c_address_demod = 0; + io->slave_select = slave_select; + + return 0; +} diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h new file mode 100644 index 000000000000..27f7cb12fad4 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cxd2880_devio_spi.h + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * I/O interface via SPI + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#ifndef CXD2880_DEVIO_SPI_H +#define CXD2880_DEVIO_SPI_H + +#include "cxd2880_common.h" +#include "cxd2880_io.h" +#include "cxd2880_spi.h" + +#include "cxd2880_tnrdmd.h" + +int cxd2880_io_spi_create(struct cxd2880_io *io, + struct cxd2880_spi *spi, + u8 slave_select); + +#endif diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h new file mode 100644 index 000000000000..2be207461847 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cxd2880_spi.h + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * SPI access definitions + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#ifndef CXD2880_SPI_H +#define CXD2880_SPI_H + +#include "cxd2880_common.h" + +enum cxd2880_spi_mode { + CXD2880_SPI_MODE_0, + CXD2880_SPI_MODE_1, + CXD2880_SPI_MODE_2, + CXD2880_SPI_MODE_3 +}; + +struct cxd2880_spi { + int (*read)(struct cxd2880_spi *spi, u8 *data, + u32 size); + int (*write)(struct cxd2880_spi *spi, const u8 *data, + u32 size); + int (*write_read)(struct cxd2880_spi *spi, + const u8 *tx_data, u32 tx_size, + u8 *rx_data, u32 rx_size); + u32 flags; + void *user; +}; + +#endif diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c new file mode 100644 index 000000000000..b8cbaa8d7aff --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cxd2880_spi_device.c + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * SPI access functions + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#include + +#include "cxd2880_spi_device.h" + +static int cxd2880_spi_device_write(struct cxd2880_spi *spi, + const u8 *data, u32 size) +{ + struct cxd2880_spi_device *spi_device = NULL; + struct spi_message msg; + struct spi_transfer tx; + int result = 0; + + if (!spi || !spi->user || !data || size == 0) + return -EINVAL; + + spi_device = spi->user; + + memset(&tx, 0, sizeof(tx)); + tx.tx_buf = data; + tx.len = size; + + spi_message_init(&msg); + spi_message_add_tail(&tx, &msg); + result = spi_sync(spi_device->spi, &msg); + + if (result < 0) + return -EIO; + + return 0; +} + +static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi, + const u8 *tx_data, + u32 tx_size, + u8 *rx_data, + u32 rx_size) +{ + struct cxd2880_spi_device *spi_device = NULL; + int result = 0; + + if (!spi || !spi->user || !tx_data || + !tx_size || !rx_data || !rx_size) + return -EINVAL; + + spi_device = spi->user; + + result = spi_write_then_read(spi_device->spi, tx_data, + tx_size, rx_data, rx_size); + if (result < 0) + return -EIO; + + return 0; +} + +int +cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, + enum cxd2880_spi_mode mode, + u32 speed_hz) +{ + int result = 0; + struct spi_device *spi = spi_device->spi; + + switch (mode) { + case CXD2880_SPI_MODE_0: + spi->mode = SPI_MODE_0; + break; + case CXD2880_SPI_MODE_1: + spi->mode = SPI_MODE_1; + break; + case CXD2880_SPI_MODE_2: + spi->mode = SPI_MODE_2; + break; + case CXD2880_SPI_MODE_3: + spi->mode = SPI_MODE_3; + break; + default: + return -EINVAL; + } + + spi->max_speed_hz = speed_hz; + spi->bits_per_word = 8; + result = spi_setup(spi); + if (result != 0) { + pr_err("spi_setup failed %d\n", result); + return -EINVAL; + } + + return 0; +} + +int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, + struct cxd2880_spi_device *spi_device) +{ + if (!spi || !spi_device) + return -EINVAL; + + spi->read = NULL; + spi->write = cxd2880_spi_device_write; + spi->write_read = cxd2880_spi_device_write_read; + spi->flags = 0; + spi->user = spi_device; + + return 0; +} diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h new file mode 100644 index 000000000000..05e3a03de3a3 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cxd2880_spi_device.h + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * SPI access interface + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#ifndef CXD2880_SPI_DEVICE_H +#define CXD2880_SPI_DEVICE_H + +#include "cxd2880_spi.h" + +struct cxd2880_spi_device { + struct spi_device *spi; +}; + +int cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, + enum cxd2880_spi_mode mode, + u32 speedHz); + +int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, + struct cxd2880_spi_device *spi_device); + +#endif /* CXD2880_SPI_DEVICE_H */ -- 2.15.1 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Subject: [PATCH v5 04/12] [media] cxd2880: Add spi device IO routines Date: Thu, 18 Jan 2018 17:48:58 +0900 Message-ID: <20180118084858.21151-1-Yasunari.Takiguchi@sony.com> References: <20180118084016.20689-1-Yasunari.Takiguchi@sony.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: <20180118084016.20689-1-Yasunari.Takiguchi@sony.com> Sender: linux-kernel-owner@vger.kernel.org To: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-media@vger.kernel.org Cc: tbird20d@gmail.com, frowand.list@gmail.com, Yasunari.Takiguchi@sony.com, Masayuki.Yamamoto@sony.com, Hideki.Nozawa@sony.com, Kota.Yonezawa@sony.com, Toshihiko.Matsumoto@sony.com, Satoshi.C.Watanabe@sony.com List-Id: devicetree@vger.kernel.org From: Yasunari Takiguchi Add functions for initializing, reading and writing to the SPI device for the Sony CXD2880 DVB-T2/T tuner + demodulator. Signed-off-by: Yasunari Takiguchi Signed-off-by: Masayuki Yamamoto Signed-off-by: Hideki Nozawa Signed-off-by: Kota Yonezawa Signed-off-by: Toshihiko Matsumoto Signed-off-by: Satoshi Watanabe --- [Change list] Changes in V5 Using SPDX-License-Identifier drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c -modified return error code -removed unnecessary parentheses drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c -removed unnecessary parentheses Changes in V4 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c -removed unnecessary initialization at variable declaration Changes in V3 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c -removed unnecessary cast -changed cxd2880_memcpy to memcpy -modified return code -changed hexadecimal code to lower case. drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h -modified return code drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h -modified return code drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c -removed unnecessary cast -modified return code drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h -modified return code .../dvb-frontends/cxd2880/cxd2880_devio_spi.c | 129 +++++++++++++++++++++ .../dvb-frontends/cxd2880/cxd2880_devio_spi.h | 23 ++++ drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h | 34 ++++++ .../dvb-frontends/cxd2880/cxd2880_spi_device.c | 113 ++++++++++++++++++ .../dvb-frontends/cxd2880/cxd2880_spi_device.h | 26 +++++ 5 files changed, 325 insertions(+) create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c create mode 100644 drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c new file mode 100644 index 000000000000..d2e37c95d748 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cxd2880_devio_spi.c + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * I/O interface via SPI + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#include "cxd2880_devio_spi.h" + +#define BURST_WRITE_MAX 128 + +static int cxd2880_io_spi_read_reg(struct cxd2880_io *io, + enum cxd2880_io_tgt tgt, + u8 sub_address, u8 *data, + u32 size) +{ + int ret; + struct cxd2880_spi *spi = NULL; + u8 send_data[6]; + u8 *read_data_top = data; + + if (!io || !io->if_object || !data) + return -EINVAL; + + if (sub_address + size > 0x100) + return -EINVAL; + + spi = io->if_object; + + if (tgt == CXD2880_IO_TGT_SYS) + send_data[0] = 0x0b; + else + send_data[0] = 0x0a; + + send_data[3] = 0; + send_data[4] = 0; + send_data[5] = 0; + + while (size > 0) { + send_data[1] = sub_address; + if (size > 255) + send_data[2] = 255; + else + send_data[2] = size; + + ret = + spi->write_read(spi, send_data, sizeof(send_data), + read_data_top, send_data[2]); + if (ret) + return ret; + + sub_address += send_data[2]; + read_data_top += send_data[2]; + size -= send_data[2]; + } + + return ret; +} + +static int cxd2880_io_spi_write_reg(struct cxd2880_io *io, + enum cxd2880_io_tgt tgt, + u8 sub_address, + const u8 *data, u32 size) +{ + int ret; + struct cxd2880_spi *spi = NULL; + u8 send_data[BURST_WRITE_MAX + 4]; + const u8 *write_data_top = data; + + if (!io || !io->if_object || !data) + return -EINVAL; + + if (size > BURST_WRITE_MAX) + return -EINVAL; + + if (sub_address + size > 0x100) + return -EINVAL; + + spi = io->if_object; + + if (tgt == CXD2880_IO_TGT_SYS) + send_data[0] = 0x0f; + else + send_data[0] = 0x0e; + + while (size > 0) { + send_data[1] = sub_address; + if (size > 255) + send_data[2] = 255; + else + send_data[2] = size; + + memcpy(&send_data[3], write_data_top, send_data[2]); + + if (tgt == CXD2880_IO_TGT_SYS) { + send_data[3 + send_data[2]] = 0x00; + ret = spi->write(spi, send_data, send_data[2] + 4); + } else { + ret = spi->write(spi, send_data, send_data[2] + 3); + } + if (ret) + return ret; + + sub_address += send_data[2]; + write_data_top += send_data[2]; + size -= send_data[2]; + } + + return ret; +} + +int cxd2880_io_spi_create(struct cxd2880_io *io, + struct cxd2880_spi *spi, u8 slave_select) +{ + if (!io || !spi) + return -EINVAL; + + io->read_regs = cxd2880_io_spi_read_reg; + io->write_regs = cxd2880_io_spi_write_reg; + io->write_reg = cxd2880_io_common_write_one_reg; + io->if_object = spi; + io->i2c_address_sys = 0; + io->i2c_address_demod = 0; + io->slave_select = slave_select; + + return 0; +} diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h new file mode 100644 index 000000000000..27f7cb12fad4 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_devio_spi.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cxd2880_devio_spi.h + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * I/O interface via SPI + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#ifndef CXD2880_DEVIO_SPI_H +#define CXD2880_DEVIO_SPI_H + +#include "cxd2880_common.h" +#include "cxd2880_io.h" +#include "cxd2880_spi.h" + +#include "cxd2880_tnrdmd.h" + +int cxd2880_io_spi_create(struct cxd2880_io *io, + struct cxd2880_spi *spi, + u8 slave_select); + +#endif diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h new file mode 100644 index 000000000000..2be207461847 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cxd2880_spi.h + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * SPI access definitions + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#ifndef CXD2880_SPI_H +#define CXD2880_SPI_H + +#include "cxd2880_common.h" + +enum cxd2880_spi_mode { + CXD2880_SPI_MODE_0, + CXD2880_SPI_MODE_1, + CXD2880_SPI_MODE_2, + CXD2880_SPI_MODE_3 +}; + +struct cxd2880_spi { + int (*read)(struct cxd2880_spi *spi, u8 *data, + u32 size); + int (*write)(struct cxd2880_spi *spi, const u8 *data, + u32 size); + int (*write_read)(struct cxd2880_spi *spi, + const u8 *tx_data, u32 tx_size, + u8 *rx_data, u32 rx_size); + u32 flags; + void *user; +}; + +#endif diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c new file mode 100644 index 000000000000..b8cbaa8d7aff --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * cxd2880_spi_device.c + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * SPI access functions + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#include + +#include "cxd2880_spi_device.h" + +static int cxd2880_spi_device_write(struct cxd2880_spi *spi, + const u8 *data, u32 size) +{ + struct cxd2880_spi_device *spi_device = NULL; + struct spi_message msg; + struct spi_transfer tx; + int result = 0; + + if (!spi || !spi->user || !data || size == 0) + return -EINVAL; + + spi_device = spi->user; + + memset(&tx, 0, sizeof(tx)); + tx.tx_buf = data; + tx.len = size; + + spi_message_init(&msg); + spi_message_add_tail(&tx, &msg); + result = spi_sync(spi_device->spi, &msg); + + if (result < 0) + return -EIO; + + return 0; +} + +static int cxd2880_spi_device_write_read(struct cxd2880_spi *spi, + const u8 *tx_data, + u32 tx_size, + u8 *rx_data, + u32 rx_size) +{ + struct cxd2880_spi_device *spi_device = NULL; + int result = 0; + + if (!spi || !spi->user || !tx_data || + !tx_size || !rx_data || !rx_size) + return -EINVAL; + + spi_device = spi->user; + + result = spi_write_then_read(spi_device->spi, tx_data, + tx_size, rx_data, rx_size); + if (result < 0) + return -EIO; + + return 0; +} + +int +cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, + enum cxd2880_spi_mode mode, + u32 speed_hz) +{ + int result = 0; + struct spi_device *spi = spi_device->spi; + + switch (mode) { + case CXD2880_SPI_MODE_0: + spi->mode = SPI_MODE_0; + break; + case CXD2880_SPI_MODE_1: + spi->mode = SPI_MODE_1; + break; + case CXD2880_SPI_MODE_2: + spi->mode = SPI_MODE_2; + break; + case CXD2880_SPI_MODE_3: + spi->mode = SPI_MODE_3; + break; + default: + return -EINVAL; + } + + spi->max_speed_hz = speed_hz; + spi->bits_per_word = 8; + result = spi_setup(spi); + if (result != 0) { + pr_err("spi_setup failed %d\n", result); + return -EINVAL; + } + + return 0; +} + +int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, + struct cxd2880_spi_device *spi_device) +{ + if (!spi || !spi_device) + return -EINVAL; + + spi->read = NULL; + spi->write = cxd2880_spi_device_write; + spi->write_read = cxd2880_spi_device_write_read; + spi->flags = 0; + spi->user = spi_device; + + return 0; +} diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h new file mode 100644 index 000000000000..05e3a03de3a3 --- /dev/null +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_spi_device.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * cxd2880_spi_device.h + * Sony CXD2880 DVB-T2/T tuner + demodulator driver + * SPI access interface + * + * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation + */ + +#ifndef CXD2880_SPI_DEVICE_H +#define CXD2880_SPI_DEVICE_H + +#include "cxd2880_spi.h" + +struct cxd2880_spi_device { + struct spi_device *spi; +}; + +int cxd2880_spi_device_initialize(struct cxd2880_spi_device *spi_device, + enum cxd2880_spi_mode mode, + u32 speedHz); + +int cxd2880_spi_device_create_spi(struct cxd2880_spi *spi, + struct cxd2880_spi_device *spi_device); + +#endif /* CXD2880_SPI_DEVICE_H */ -- 2.15.1