/*
* Twofish for CryptoAPI
*
* Originally Twofish for GPG
* By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
* 256-bit key length added March 20, 1999
* Some modifications to reduce the text size by Werner Koch, April, 1998
* Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
* Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
*
* The original author has disclaimed all copyright interest in this
* code and thus put it in the public domain. The subsequent authors
* have put this under the GNU General Public License.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
* This code is a "clean room" implementation, written from the paper
* _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
* Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
* through http://www.counterpane.com/twofish.html
*
* For background information on multiplication in finite fields, used for
* the matrix operations in the key schedule, see the book _Contemporary
* Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
* Third Edition.
*/
#include <asm/byteorder.h>
#include <crypto/twofish.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/crypto.h>
#include <linux/bitops.h>
/* Macros to compute the g() function in the encryption and decryption
* rounds. G1 is the straight g() function; G2 includes the 8-bit
* rotation for the high 32-bit word. */
#define G1(a) \
(ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
#define G2(b) \
(ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
/* Encryption and decryption Feistel rounds. Each one calls the two g()
* macros, does the PHT, and performs the XOR and the appropriate bit
* rotations. The parameters are the round number (used to select subkeys),
* and the four 32-bit chunks of the text. */
#define ENCROUND(n, a, b, c, d) \
x = G1 (a); y = G2 (b); \
x += y; y += x + ctx->k[2 * (n) + 1]; \
(c) ^= x + ctx->k[2 * (n)]; \
(c) = ror32((c), 1); \
(d) = rol32((d), 1) ^ y
#define DECROUND(n, a, b, c, d) \
x = G1 (a); y = G2 (b); \
x += y; y += x; \
(d) ^= y + ctx->k[2 * (n) + 1]; \
(d) = ror32((d), 1); \
(c) = rol32((c), 1); \
(c) ^= (x + ctx->k[2 * (n)])
/* Encryption and decryption cycles; each one is simply two Feistel rounds
* with the 32-bit chunks re-ordered to simulate the "swap" */
#define ENCCYCLE(n) \
ENCROUND (2 * (n), a, b, c, d); \
ENCROUND (2 * (n) + 1, c, d, a, b)
#define DECCYCLE(n) \
DECROUND (2 * (n) + 1, c, d, a, b); \
DECROUND (2 * (n), a, b, c, d)
/* Macros to convert the input and output bytes into 32-bit words,
* and simultaneously perform the whitening step. INPACK packs word
* number n into the variable named by x, using whitening subkey number m.
* OUTUNPACK unpacks word number n from the variable named by x, using
* whitening subkey number m. */
#define INPACK(n, x, m) \
x = le32_to_cpu(src[n]) ^ ctx->w[m]
#define OUTUNPACK(n, x, m) \
x ^= ctx->w[m]; \
dst[n] = cpu_to_le32(x)
/* Encrypt one block. in and out may be the same. */
static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *src = (const __le32 *)in;
__le32 *dst = (__le32 *)out;
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
/* Temporaries used by the round function. */
u32 x, y;
/* Input whitening and packing. */
INPACK (0, a, 0);
INPACK (1, b, 1);
INPACK (2, c, 2);
INPACK (3, d, 3);
/* Encryption Feistel cycles. */
ENCCYCLE (0);
ENCCYCLE (1);
ENCCYCLE (2);
ENCCYCLE (3);
ENCCYCLE (4);
ENCCYCLE (5);
ENCCYCLE (6);
ENCCYCLE (7);
/* Output whitening and unpacking. */
OUTUNPACK (0, c, 4);
OUTUNPACK (1, d, 5);
OUTUNPACK (2, a, 6);
OUTUNPACK (3, b, 7);
}
/* Decrypt one block. in and out may be the same. */
static void twofish_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
const __le32 *src = (const __le32 *)in;
__le32 *dst = (__le32 *)out;
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
/* Temporaries used by the round function. */
u32 x, y;
/* Input whitening and packing. */
INPACK (0, c, 4);
INPACK (1, d, 5pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//*
* Copyright (C) 2006-2008 Michael Hennerich, Analog Devices Inc.
*
* Description: AD7877 based touchscreen, sensor (ADCs), DAC and GPIO driver
* Based on: ads7846.c
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see the file COPYING, or write
* to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* History:
* Copyright (c) 2005 David Brownell
* Copyright (c) 2006 Nokia Corporation
* Various changes: Imre Deak <imre.deak@nokia.com>
*
* Using code from:
* - corgi_ts.c
* Copyright (C) 2004-2005 Richard Purdie
* - omap_ts.[hc], ads7846.h, ts_osk.c
* Copyright (C) 2002 MontaVista Software
* Copyright (C) 2004 Texas Instruments
* Copyright (C) 2005 Dirk Behme
*/
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/spi/ad7877.h>
#include <linux/module.h>
#include <asm/irq.h>
#define TS_PEN_UP_TIMEOUT msecs_to_jiffies(100)
#define MAX_SPI_FREQ_HZ 20000000
#define MAX_12BIT ((1<<12)-1)
#define AD7877_REG_ZEROS 0
#define AD7877_REG_CTRL1 1
#define AD7877_REG_CTRL2 2
#define AD7877_REG_ALERT 3
#define AD7877_REG_AUX1HIGH 4
#define AD7877_REG_AUX1LOW 5
#define AD7877_REG_BAT1HIGH 6
#define AD7877_REG_BAT1LOW 7
#define AD7877_REG_BAT2HIGH 8
#define AD7877_REG_BAT2LOW 9
#define AD7877_REG_TEMP1HIGH 10
#define AD7877_REG_TEMP1LOW 11
#define AD7877_REG_SEQ0 12
#define AD7877_REG_SEQ1 13
#define AD7877_REG_DAC 14
#define AD7877_REG_NONE1 15
#define AD7877_REG_EXTWRITE 15
#define AD7877_REG_XPLUS 16
#define AD7877_REG_YPLUS 17
#define AD7877_REG_Z2 18
#define AD7877_REG_aux1 19
#define AD7877_REG_aux2 20
#define AD7877_REG_aux3 21
#define AD7877_REG_bat1 22
#define AD7877_REG_bat2 23
#define AD7877_REG_temp1 24
#define AD7877_REG_temp2 25
#define AD7877_REG_Z1 26
#define AD7877_REG_GPIOCTRL1 27
#define AD7877_REG_GPIOCTRL2 28
#define AD7877_REG_GPIODATA 29
#define AD7877_REG_NONE2 30
#define AD7877_REG_NONE3 31
#define AD7877_SEQ_YPLUS_BIT (1<<11)
#define AD7877_SEQ_XPLUS_BIT (1<<10)
#define AD7877_SEQ_Z2_BIT (1<<9)
#define AD7877_SEQ_AUX1_BIT (1<<8)
#define AD7877_SEQ_AUX2_BIT (1<<7)
#define AD7877_SEQ_AUX3_BIT (1<<6)
#define AD7877_SEQ_BAT1_BIT (1<<5)
#define AD7877_SEQ_BAT2_BIT (1<<4)
#define AD7877_SEQ_TEMP1_BIT (1<<3)
#define AD7877_SEQ_TEMP2_BIT (1<<2)
#define AD7877_SEQ_Z1_BIT (1<<1)
enum {
AD7877_SEQ_YPOS = 0,
AD7877_SEQ_XPOS = 1,
AD7877_SEQ_Z2 = 2,
AD7877_SEQ_AUX1 = 3,
AD7877_SEQ_AUX2 = 4,
AD7877_SEQ_AUX3 = 5,
AD7877_SEQ_BAT1 = 6,
AD7877_SEQ_BAT2 = 7,
AD7877_SEQ_TEMP1 = 8,
AD7877_SEQ_TEMP2 = 9,
AD7877_SEQ_Z1 = 10,
AD7877_NR_SENSE = 11,
};
/* DAC Register Default RANGE 0 to Vcc, Volatge Mode, DAC On */
#define AD7877_DAC_CONF 0x1
/* If gpio3 is set AUX3/GPIO3 acts as GPIO Output */
#define AD7877_EXTW_GPIO_3_CONF 0x1C4
#define AD7877_EXTW_GPIO_DATA 0x200
/* Control REG 2 */
#define AD7877_TMR(x) ((x & 0x3) << 0)
#define AD7877_REF(x) ((x & 0x1) << 2)
#define AD7877_POL(x) ((x & 0x1) << 3)
#define AD7877_FCD(x) ((x & 0x3) << 4)
#define AD7877_PM(x) ((x & 0x3) << 6)
#define AD7877_ACQ(x) ((x & 0x3) << 8)
#define AD7877_AVG(x) ((x & 0x3) << 10)
/* Control REG 1 */
#define AD7877_SER (1 << 11) /* non-differential */
#define AD7877_DFR (0 << 11) /* differential */
#define AD7877_MODE_NOC (0) /* Do not convert */
#define AD7877_MODE_SCC (1) /* Single channel conversion */
#define AD7877_MODE_SEQ0 (2) /* Sequence 0 in Slave Mode */
#define AD7877_MODE_SEQ1 (3) /* Sequence 1 in Master Mode */
#define AD7877_CHANADD(x) ((x&0xF)<<7)
#define AD7877_READADD(x) ((x)<<2)
#define AD7877_WRITEADD(x) ((x)<<12)
#define AD7877_READ_CHAN(x) (AD7877_WRITEADD(AD7877_REG_CTRL1) | AD7877_SER | \
AD7877_MODE_SCC | AD7877_CHANADD(AD7877_REG_ ## x) | \
AD7877_READADD(AD7877_REG_ ## x))
#define AD7877_MM_SEQUENCE (AD7877_SEQ_YPLUS_BIT | AD7877_SEQ_XPLUS_BIT | \
AD7877_SEQ_Z2_BIT | AD7877_SEQ_Z1_BIT)
/*
* Non-touchscreen sensors only use single-ended conversions.
*/
struct ser_req {
u16 reset;
u16 ref_on;
u16 command;
struct spi_message msg;
struct spi_transfer xfer[6];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
u16 sample ____cacheline_aligned;
};
struct ad7877 {
struct input_dev *input;
char phys[32];
struct spi_device *spi;
u16 model;
u16 vref_delay_usecs;
u16 x_plate_ohms;
u16 pressure_max;
u16 cmd_crtl1;
u16 cmd_crtl2;
u16 cmd_dummy;
u16 dac;
u8 stopacq_polarity;
u8 first_conversion_delay;
u8 acquisition_time;
u8 averaging;
u8 pen_down_acc_interval;
struct spi_transfer xfer[AD7877_NR_SENSE + 2];
struct spi_message msg;
struct mutex mutex;
bool disabled; /* P: mutex */
bool gpio3; /* P: mutex */
bool gpio4; /* P: mutex */
spinlock_t lock;
struct timer_list timer; /* P: lock */
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
u16 conversion_data[AD7877_NR_SENSE] ____cacheline_aligned;
};
static bool gpio3;
module_param(gpio3, bool, 0);
MODULE_PARM_DESC(gpio3, "If gpio3 is set to 1 AUX3 acts as GPIO3");
static int ad7877_read(struct spi_device *spi, u16 reg)
{
struct ser_req *req;
int status, ret;
req = kzalloc(sizeof *req, GFP_KERNEL);
if (!req)
return -ENOMEM;
spi_message_init(&req->msg);
req->command = (u16) (AD7877_WRITEADD(AD7877_REG_CTRL1) |
AD7877_READADD(reg));
req->xfer[0].tx_buf = &req->command;
req->xfer[0].len = 2;
req->xfer[0].cs_change = 1;
req->xfer[1].rx_buf = &req->sample;
req->xfer[1].len = 2;
spi_message_add_tail(&req->xfer[0], &req->msg);
spi_message_add_tail(&req->xfer[1], &req->msg);
status = spi_sync(spi, &req->msg);
ret = status ? : req->sample;
kfree(req);
return ret;
}
static int ad7877_write(struct spi_device *spi, u16 reg, u16 val)
{
struct ser_req *req;
int status;
req = kzalloc(sizeof *req, GFP_KERNEL);
if (!req)
return -ENOMEM;
spi_message_init(&req->msg);
req->command = (u16) (AD7877_WRITEADD(reg) | (val & MAX_12BIT));
req->xfer[0].tx_buf = &req->command;
req->xfer[0].len = 2;
spi_message_add_tail(&req->xfer[0], &req->msg);
status = spi_sync(spi,