qemu/hw/input/tsc210x.c
<<
>>
Prefs
   1/*
   2 * TI TSC2102 (touchscreen/sensors/audio controller) emulator.
   3 * TI TSC2301 (touchscreen/sensors/keypad).
   4 *
   5 * Copyright (c) 2006 Andrzej Zaborowski  <balrog@zabor.org>
   6 * Copyright (C) 2008 Nokia Corporation
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 or
  11 * (at your option) version 3 of the License.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License along
  19 * with this program; if not, see <http://www.gnu.org/licenses/>.
  20 */
  21
  22#include "qemu/osdep.h"
  23#include "qemu/log.h"
  24#include "hw/hw.h"
  25#include "audio/audio.h"
  26#include "qemu/timer.h"
  27#include "qemu/log.h"
  28#include "sysemu/reset.h"
  29#include "ui/console.h"
  30#include "hw/arm/omap.h"            /* For I2SCodec */
  31#include "hw/input/tsc2xxx.h"
  32#include "hw/irq.h"
  33#include "migration/vmstate.h"
  34
  35#define TSC_DATA_REGISTERS_PAGE         0x0
  36#define TSC_CONTROL_REGISTERS_PAGE      0x1
  37#define TSC_AUDIO_REGISTERS_PAGE        0x2
  38
  39#define TSC_VERBOSE
  40
  41#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - resolution[p]))
  42
  43typedef struct {
  44    qemu_irq pint;
  45    qemu_irq kbint;
  46    qemu_irq davint;
  47    QEMUTimer *timer;
  48    QEMUSoundCard card;
  49    uWireSlave chip;
  50    I2SCodec codec;
  51    uint8_t in_fifo[16384];
  52    uint8_t out_fifo[16384];
  53    uint16_t model;
  54
  55    int32_t x, y;
  56    bool pressure;
  57
  58    uint8_t page, offset;
  59    uint16_t dav;
  60
  61    bool state;
  62    bool irq;
  63    bool command;
  64    bool busy;
  65    bool enabled;
  66    bool host_mode;
  67    uint8_t function, nextfunction;
  68    uint8_t precision, nextprecision;
  69    uint8_t filter;
  70    uint8_t pin_func;
  71    uint8_t ref;
  72    uint8_t timing;
  73    uint8_t noise;
  74
  75    uint16_t audio_ctrl1;
  76    uint16_t audio_ctrl2;
  77    uint16_t audio_ctrl3;
  78    uint16_t pll[3];
  79    uint16_t volume;
  80    int64_t volume_change;
  81    bool softstep;
  82    uint16_t dac_power;
  83    int64_t powerdown;
  84    uint16_t filter_data[0x14];
  85
  86    const char *name;
  87    SWVoiceIn *adc_voice[1];
  88    SWVoiceOut *dac_voice[1];
  89    int i2s_rx_rate;
  90    int i2s_tx_rate;
  91
  92    int tr[8];
  93
  94    struct {
  95        uint16_t down;
  96        uint16_t mask;
  97        int scan;
  98        int debounce;
  99        int mode;
 100        int intr;
 101    } kb;
 102    int64_t now; /* Time at migration */
 103} TSC210xState;
 104
 105static const int resolution[4] = { 12, 8, 10, 12 };
 106
 107#define TSC_MODE_NO_SCAN        0x0
 108#define TSC_MODE_XY_SCAN        0x1
 109#define TSC_MODE_XYZ_SCAN       0x2
 110#define TSC_MODE_X              0x3
 111#define TSC_MODE_Y              0x4
 112#define TSC_MODE_Z              0x5
 113#define TSC_MODE_BAT1           0x6
 114#define TSC_MODE_BAT2           0x7
 115#define TSC_MODE_AUX            0x8
 116#define TSC_MODE_AUX_SCAN       0x9
 117#define TSC_MODE_TEMP1          0xa
 118#define TSC_MODE_PORT_SCAN      0xb
 119#define TSC_MODE_TEMP2          0xc
 120#define TSC_MODE_XX_DRV         0xd
 121#define TSC_MODE_YY_DRV         0xe
 122#define TSC_MODE_YX_DRV         0xf
 123
 124static const uint16_t mode_regs[16] = {
 125    0x0000,     /* No scan */
 126    0x0600,     /* X, Y scan */
 127    0x0780,     /* X, Y, Z scan */
 128    0x0400,     /* X */
 129    0x0200,     /* Y */
 130    0x0180,     /* Z */
 131    0x0040,     /* BAT1 */
 132    0x0030,     /* BAT2 */
 133    0x0010,     /* AUX */
 134    0x0010,     /* AUX scan */
 135    0x0004,     /* TEMP1 */
 136    0x0070,     /* Port scan */
 137    0x0002,     /* TEMP2 */
 138    0x0000,     /* X+, X- drivers */
 139    0x0000,     /* Y+, Y- drivers */
 140    0x0000,     /* Y+, X- drivers */
 141};
 142
 143#define X_TRANSFORM(s)                  \
 144    ((s->y * s->tr[0] - s->x * s->tr[1]) / s->tr[2] + s->tr[3])
 145#define Y_TRANSFORM(s)                  \
 146    ((s->y * s->tr[4] - s->x * s->tr[5]) / s->tr[6] + s->tr[7])
 147#define Z1_TRANSFORM(s)                 \
 148    ((400 - ((s)->x >> 7) + ((s)->pressure << 10)) << 4)
 149#define Z2_TRANSFORM(s)                 \
 150    ((4000 + ((s)->y >> 7) - ((s)->pressure << 10)) << 4)
 151
 152#define BAT1_VAL                        0x8660
 153#define BAT2_VAL                        0x0000
 154#define AUX1_VAL                        0x35c0
 155#define AUX2_VAL                        0xffff
 156#define TEMP1_VAL                       0x8c70
 157#define TEMP2_VAL                       0xa5b0
 158
 159#define TSC_POWEROFF_DELAY              50
 160#define TSC_SOFTSTEP_DELAY              50
 161
 162static void tsc210x_reset(TSC210xState *s)
 163{
 164    s->state = false;
 165    s->pin_func = 2;
 166    s->enabled = false;
 167    s->busy = false;
 168    s->nextfunction = 0;
 169    s->ref = 0;
 170    s->timing = 0;
 171    s->irq = false;
 172    s->dav = 0;
 173
 174    s->audio_ctrl1 = 0x0000;
 175    s->audio_ctrl2 = 0x4410;
 176    s->audio_ctrl3 = 0x0000;
 177    s->pll[0] = 0x1004;
 178    s->pll[1] = 0x0000;
 179    s->pll[2] = 0x1fff;
 180    s->volume = 0xffff;
 181    s->dac_power = 0x8540;
 182    s->softstep = true;
 183    s->volume_change = 0;
 184    s->powerdown = 0;
 185    s->filter_data[0x00] = 0x6be3;
 186    s->filter_data[0x01] = 0x9666;
 187    s->filter_data[0x02] = 0x675d;
 188    s->filter_data[0x03] = 0x6be3;
 189    s->filter_data[0x04] = 0x9666;
 190    s->filter_data[0x05] = 0x675d;
 191    s->filter_data[0x06] = 0x7d83;
 192    s->filter_data[0x07] = 0x84ee;
 193    s->filter_data[0x08] = 0x7d83;
 194    s->filter_data[0x09] = 0x84ee;
 195    s->filter_data[0x0a] = 0x6be3;
 196    s->filter_data[0x0b] = 0x9666;
 197    s->filter_data[0x0c] = 0x675d;
 198    s->filter_data[0x0d] = 0x6be3;
 199    s->filter_data[0x0e] = 0x9666;
 200    s->filter_data[0x0f] = 0x675d;
 201    s->filter_data[0x10] = 0x7d83;
 202    s->filter_data[0x11] = 0x84ee;
 203    s->filter_data[0x12] = 0x7d83;
 204    s->filter_data[0x13] = 0x84ee;
 205
 206    s->i2s_tx_rate = 0;
 207    s->i2s_rx_rate = 0;
 208
 209    s->kb.scan = 1;
 210    s->kb.debounce = 0;
 211    s->kb.mask = 0x0000;
 212    s->kb.mode = 3;
 213    s->kb.intr = 0;
 214
 215    qemu_set_irq(s->pint, !s->irq);
 216    qemu_set_irq(s->davint, !s->dav);
 217    qemu_irq_raise(s->kbint);
 218}
 219
 220typedef struct {
 221    int rate;
 222    int dsor;
 223    int fsref;
 224} TSC210xRateInfo;
 225
 226/*  { rate,   dsor, fsref }     */
 227static const TSC210xRateInfo tsc2102_rates[] = {
 228    /* Fsref / 6.0 */
 229    { 7350,     63,     1 },
 230    { 8000,     63,     0 },
 231    /* Fsref / 6.0 */
 232    { 7350,     54,     1 },
 233    { 8000,     54,     0 },
 234    /* Fsref / 5.0 */
 235    { 8820,     45,     1 },
 236    { 9600,     45,     0 },
 237    /* Fsref / 4.0 */
 238    { 11025,    36,     1 },
 239    { 12000,    36,     0 },
 240    /* Fsref / 3.0 */
 241    { 14700,    27,     1 },
 242    { 16000,    27,     0 },
 243    /* Fsref / 2.0 */
 244    { 22050,    18,     1 },
 245    { 24000,    18,     0 },
 246    /* Fsref / 1.5 */
 247    { 29400,    9,      1 },
 248    { 32000,    9,      0 },
 249    /* Fsref */
 250    { 44100,    0,      1 },
 251    { 48000,    0,      0 },
 252
 253    { 0,        0,      0 },
 254};
 255
 256static inline void tsc210x_out_flush(TSC210xState *s, int len)
 257{
 258    uint8_t *data = s->codec.out.fifo + s->codec.out.start;
 259    uint8_t *end = data + len;
 260
 261    while (data < end)
 262        data += AUD_write(s->dac_voice[0], data, end - data) ?: (end - data);
 263
 264    s->codec.out.len -= len;
 265    if (s->codec.out.len)
 266        memmove(s->codec.out.fifo, end, s->codec.out.len);
 267    s->codec.out.start = 0;
 268}
 269
 270static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
 271{
 272    if (s->codec.out.len >= free_b) {
 273        tsc210x_out_flush(s, free_b);
 274        return;
 275    }
 276
 277    s->codec.out.size = MIN(free_b, 16384);
 278    qemu_irq_raise(s->codec.tx_start);
 279}
 280
 281static void tsc2102_audio_rate_update(TSC210xState *s)
 282{
 283    const TSC210xRateInfo *rate;
 284
 285    s->codec.tx_rate = 0;
 286    s->codec.rx_rate = 0;
 287    if (s->dac_power & (1 << 15))                               /* PWDNC */
 288        return;
 289
 290    for (rate = tsc2102_rates; rate->rate; rate ++)
 291        if (rate->dsor == (s->audio_ctrl1 & 0x3f) &&            /* DACFS */
 292                        rate->fsref == ((s->audio_ctrl3 >> 13) & 1))/* REFFS */
 293            break;
 294    if (!rate->rate) {
 295        printf("%s: unknown sampling rate configured\n", __func__);
 296        return;
 297    }
 298
 299    s->codec.tx_rate = rate->rate;
 300}
 301
 302static void tsc2102_audio_output_update(TSC210xState *s)
 303{
 304    int enable;
 305    struct audsettings fmt;
 306
 307    if (s->dac_voice[0]) {
 308        tsc210x_out_flush(s, s->codec.out.len);
 309        s->codec.out.size = 0;
 310        AUD_set_active_out(s->dac_voice[0], 0);
 311        AUD_close_out(&s->card, s->dac_voice[0]);
 312        s->dac_voice[0] = NULL;
 313    }
 314    s->codec.cts = 0;
 315
 316    enable =
 317            (~s->dac_power & (1 << 15)) &&                      /* PWDNC */
 318            (~s->dac_power & (1 << 10));                        /* DAPWDN */
 319    if (!enable || !s->codec.tx_rate)
 320        return;
 321
 322    /* Force our own sampling rate even in slave DAC mode */
 323    fmt.endianness = 0;
 324    fmt.nchannels = 2;
 325    fmt.freq = s->codec.tx_rate;
 326    fmt.fmt = AUDIO_FORMAT_S16;
 327
 328    s->dac_voice[0] = AUD_open_out(&s->card, s->dac_voice[0],
 329                    "tsc2102.sink", s, (void *) tsc210x_audio_out_cb, &fmt);
 330    if (s->dac_voice[0]) {
 331        s->codec.cts = 1;
 332        AUD_set_active_out(s->dac_voice[0], 1);
 333    }
 334}
 335
 336static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
 337{
 338    switch (reg) {
 339    case 0x00:  /* X */
 340        s->dav &= 0xfbff;
 341        return TSC_CUT_RESOLUTION(X_TRANSFORM(s), s->precision) +
 342                (s->noise & 3);
 343
 344    case 0x01:  /* Y */
 345        s->noise ++;
 346        s->dav &= 0xfdff;
 347        return TSC_CUT_RESOLUTION(Y_TRANSFORM(s), s->precision) ^
 348                (s->noise & 3);
 349
 350    case 0x02:  /* Z1 */
 351        s->dav &= 0xfeff;
 352        return TSC_CUT_RESOLUTION(Z1_TRANSFORM(s), s->precision) -
 353                (s->noise & 3);
 354
 355    case 0x03:  /* Z2 */
 356        s->dav &= 0xff7f;
 357        return TSC_CUT_RESOLUTION(Z2_TRANSFORM(s), s->precision) |
 358                (s->noise & 3);
 359
 360    case 0x04:  /* KPData */
 361        if ((s->model & 0xff00) == 0x2300) {
 362            if (s->kb.intr && (s->kb.mode & 2)) {
 363                s->kb.intr = 0;
 364                qemu_irq_raise(s->kbint);
 365            }
 366            return s->kb.down;
 367        }
 368
 369        return 0xffff;
 370
 371    case 0x05:  /* BAT1 */
 372        s->dav &= 0xffbf;
 373        return TSC_CUT_RESOLUTION(BAT1_VAL, s->precision) +
 374                (s->noise & 6);
 375
 376    case 0x06:  /* BAT2 */
 377        s->dav &= 0xffdf;
 378        return TSC_CUT_RESOLUTION(BAT2_VAL, s->precision);
 379
 380    case 0x07:  /* AUX1 */
 381        s->dav &= 0xffef;
 382        return TSC_CUT_RESOLUTION(AUX1_VAL, s->precision);
 383
 384    case 0x08:  /* AUX2 */
 385        s->dav &= 0xfff7;
 386        return 0xffff;
 387
 388    case 0x09:  /* TEMP1 */
 389        s->dav &= 0xfffb;
 390        return TSC_CUT_RESOLUTION(TEMP1_VAL, s->precision) -
 391                (s->noise & 5);
 392
 393    case 0x0a:  /* TEMP2 */
 394        s->dav &= 0xfffd;
 395        return TSC_CUT_RESOLUTION(TEMP2_VAL, s->precision) ^
 396                (s->noise & 3);
 397
 398    case 0x0b:  /* DAC */
 399        s->dav &= 0xfffe;
 400        return 0xffff;
 401
 402    default:
 403#ifdef TSC_VERBOSE
 404        fprintf(stderr, "tsc2102_data_register_read: "
 405                        "no such register: 0x%02x\n", reg);
 406#endif
 407        return 0xffff;
 408    }
 409}
 410
 411static uint16_t tsc2102_control_register_read(
 412                TSC210xState *s, int reg)
 413{
 414    switch (reg) {
 415    case 0x00:  /* TSC ADC */
 416        return (s->pressure << 15) | ((!s->busy) << 14) |
 417                (s->nextfunction << 10) | (s->nextprecision << 8) | s->filter; 
 418
 419    case 0x01:  /* Status / Keypad Control */
 420        if ((s->model & 0xff00) == 0x2100)
 421            return (s->pin_func << 14) | ((!s->enabled) << 13) |
 422                    (s->host_mode << 12) | ((!!s->dav) << 11) | s->dav;
 423        else
 424            return (s->kb.intr << 15) | ((s->kb.scan || !s->kb.down) << 14) |
 425                    (s->kb.debounce << 11);
 426
 427    case 0x02:  /* DAC Control */
 428        if ((s->model & 0xff00) == 0x2300)
 429            return s->dac_power & 0x8000;
 430        else
 431            goto bad_reg;
 432
 433    case 0x03:  /* Reference */
 434        return s->ref;
 435
 436    case 0x04:  /* Reset */
 437        return 0xffff;
 438
 439    case 0x05:  /* Configuration */
 440        return s->timing;
 441
 442    case 0x06:  /* Secondary configuration */
 443        if ((s->model & 0xff00) == 0x2100)
 444            goto bad_reg;
 445        return ((!s->dav) << 15) | ((s->kb.mode & 1) << 14) | s->pll[2];
 446
 447    case 0x10:  /* Keypad Mask */
 448        if ((s->model & 0xff00) == 0x2100)
 449            goto bad_reg;
 450        return s->kb.mask;
 451
 452    default:
 453    bad_reg:
 454#ifdef TSC_VERBOSE
 455        fprintf(stderr, "tsc2102_control_register_read: "
 456                        "no such register: 0x%02x\n", reg);
 457#endif
 458        return 0xffff;
 459    }
 460}
 461
 462static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
 463{
 464    int l_ch, r_ch;
 465    uint16_t val;
 466
 467    switch (reg) {
 468    case 0x00:  /* Audio Control 1 */
 469        return s->audio_ctrl1;
 470
 471    case 0x01:
 472        return 0xff00;
 473
 474    case 0x02:  /* DAC Volume Control */
 475        return s->volume;
 476
 477    case 0x03:
 478        return 0x8b00;
 479
 480    case 0x04:  /* Audio Control 2 */
 481        l_ch = 1;
 482        r_ch = 1;
 483        if (s->softstep && !(s->dac_power & (1 << 10))) {
 484            l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
 485                            s->volume_change + TSC_SOFTSTEP_DELAY);
 486            r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
 487                            s->volume_change + TSC_SOFTSTEP_DELAY);
 488        }
 489
 490        return s->audio_ctrl2 | (l_ch << 3) | (r_ch << 2);
 491
 492    case 0x05:  /* Stereo DAC Power Control */
 493        return 0x2aa0 | s->dac_power |
 494                (((s->dac_power & (1 << 10)) &&
 495                  (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
 496                   s->powerdown + TSC_POWEROFF_DELAY)) << 6);
 497
 498    case 0x06:  /* Audio Control 3 */
 499        val = s->audio_ctrl3 | 0x0001;
 500        s->audio_ctrl3 &= 0xff3f;
 501        return val;
 502
 503    case 0x07:  /* LCH_BASS_BOOST_N0 */
 504    case 0x08:  /* LCH_BASS_BOOST_N1 */
 505    case 0x09:  /* LCH_BASS_BOOST_N2 */
 506    case 0x0a:  /* LCH_BASS_BOOST_N3 */
 507    case 0x0b:  /* LCH_BASS_BOOST_N4 */
 508    case 0x0c:  /* LCH_BASS_BOOST_N5 */
 509    case 0x0d:  /* LCH_BASS_BOOST_D1 */
 510    case 0x0e:  /* LCH_BASS_BOOST_D2 */
 511    case 0x0f:  /* LCH_BASS_BOOST_D4 */
 512    case 0x10:  /* LCH_BASS_BOOST_D5 */
 513    case 0x11:  /* RCH_BASS_BOOST_N0 */
 514    case 0x12:  /* RCH_BASS_BOOST_N1 */
 515    case 0x13:  /* RCH_BASS_BOOST_N2 */
 516    case 0x14:  /* RCH_BASS_BOOST_N3 */
 517    case 0x15:  /* RCH_BASS_BOOST_N4 */
 518    case 0x16:  /* RCH_BASS_BOOST_N5 */
 519    case 0x17:  /* RCH_BASS_BOOST_D1 */
 520    case 0x18:  /* RCH_BASS_BOOST_D2 */
 521    case 0x19:  /* RCH_BASS_BOOST_D4 */
 522    case 0x1a:  /* RCH_BASS_BOOST_D5 */
 523        return s->filter_data[reg - 0x07];
 524
 525    case 0x1b:  /* PLL Programmability 1 */
 526        return s->pll[0];
 527
 528    case 0x1c:  /* PLL Programmability 2 */
 529        return s->pll[1];
 530
 531    case 0x1d:  /* Audio Control 4 */
 532        return (!s->softstep) << 14;
 533
 534    default:
 535#ifdef TSC_VERBOSE
 536        fprintf(stderr, "tsc2102_audio_register_read: "
 537                        "no such register: 0x%02x\n", reg);
 538#endif
 539        return 0xffff;
 540    }
 541}
 542
 543static void tsc2102_data_register_write(
 544                TSC210xState *s, int reg, uint16_t value)
 545{
 546    switch (reg) {
 547    case 0x00:  /* X */
 548    case 0x01:  /* Y */
 549    case 0x02:  /* Z1 */
 550    case 0x03:  /* Z2 */
 551    case 0x05:  /* BAT1 */
 552    case 0x06:  /* BAT2 */
 553    case 0x07:  /* AUX1 */
 554    case 0x08:  /* AUX2 */
 555    case 0x09:  /* TEMP1 */
 556    case 0x0a:  /* TEMP2 */
 557        return;
 558
 559    default:
 560        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_data_register_write: "
 561                                       "no such register: 0x%02x\n", reg);
 562    }
 563}
 564
 565static void tsc2102_control_register_write(
 566                TSC210xState *s, int reg, uint16_t value)
 567{
 568    switch (reg) {
 569    case 0x00:  /* TSC ADC */
 570        s->host_mode = value >> 15;
 571        s->enabled = !(value & 0x4000);
 572        if (s->busy && !s->enabled)
 573            timer_del(s->timer);
 574        s->busy = s->busy && s->enabled;
 575        s->nextfunction = (value >> 10) & 0xf;
 576        s->nextprecision = (value >> 8) & 3;
 577        s->filter = value & 0xff;
 578        return;
 579
 580    case 0x01:  /* Status / Keypad Control */
 581        if ((s->model & 0xff00) == 0x2100)
 582            s->pin_func = value >> 14;
 583        else {
 584            s->kb.scan = (value >> 14) & 1;
 585            s->kb.debounce = (value >> 11) & 7;
 586            if (s->kb.intr && s->kb.scan) {
 587                s->kb.intr = 0;
 588                qemu_irq_raise(s->kbint);
 589            }
 590        }
 591        return;
 592
 593    case 0x02:  /* DAC Control */
 594        if ((s->model & 0xff00) == 0x2300) {
 595            s->dac_power &= 0x7fff;
 596            s->dac_power |= 0x8000 & value;
 597        } else
 598            goto bad_reg;
 599        break;
 600
 601    case 0x03:  /* Reference */
 602        s->ref = value & 0x1f;
 603        return;
 604
 605    case 0x04:  /* Reset */
 606        if (value == 0xbb00) {
 607            if (s->busy)
 608                timer_del(s->timer);
 609            tsc210x_reset(s);
 610#ifdef TSC_VERBOSE
 611        } else {
 612            fprintf(stderr, "tsc2102_control_register_write: "
 613                            "wrong value written into RESET\n");
 614#endif
 615        }
 616        return;
 617
 618    case 0x05:  /* Configuration */
 619        s->timing = value & 0x3f;
 620#ifdef TSC_VERBOSE
 621        if (value & ~0x3f)
 622            fprintf(stderr, "tsc2102_control_register_write: "
 623                            "wrong value written into CONFIG\n");
 624#endif
 625        return;
 626
 627    case 0x06:  /* Secondary configuration */
 628        if ((s->model & 0xff00) == 0x2100)
 629            goto bad_reg;
 630        s->kb.mode = value >> 14;
 631        s->pll[2] = value & 0x3ffff;
 632        return;
 633
 634    case 0x10:  /* Keypad Mask */
 635        if ((s->model & 0xff00) == 0x2100)
 636            goto bad_reg;
 637        s->kb.mask = value;
 638        return;
 639
 640    default:
 641    bad_reg:
 642        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_control_register_write: "
 643                                       "no such register: 0x%02x\n", reg);
 644    }
 645}
 646
 647static void tsc2102_audio_register_write(
 648                TSC210xState *s, int reg, uint16_t value)
 649{
 650    switch (reg) {
 651    case 0x00:  /* Audio Control 1 */
 652        s->audio_ctrl1 = value & 0x0f3f;
 653#ifdef TSC_VERBOSE
 654        if ((value & ~0x0f3f) || ((value & 7) != ((value >> 3) & 7)))
 655            fprintf(stderr, "tsc2102_audio_register_write: "
 656                            "wrong value written into Audio 1\n");
 657#endif
 658        tsc2102_audio_rate_update(s);
 659        tsc2102_audio_output_update(s);
 660        return;
 661
 662    case 0x01:
 663#ifdef TSC_VERBOSE
 664        if (value != 0xff00)
 665            fprintf(stderr, "tsc2102_audio_register_write: "
 666                            "wrong value written into reg 0x01\n");
 667#endif
 668        return;
 669
 670    case 0x02:  /* DAC Volume Control */
 671        s->volume = value;
 672        s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 673        return;
 674
 675    case 0x03:
 676#ifdef TSC_VERBOSE
 677        if (value != 0x8b00)
 678            fprintf(stderr, "tsc2102_audio_register_write: "
 679                            "wrong value written into reg 0x03\n");
 680#endif
 681        return;
 682
 683    case 0x04:  /* Audio Control 2 */
 684        s->audio_ctrl2 = value & 0xf7f2;
 685#ifdef TSC_VERBOSE
 686        if (value & ~0xf7fd)
 687            fprintf(stderr, "tsc2102_audio_register_write: "
 688                            "wrong value written into Audio 2\n");
 689#endif
 690        return;
 691
 692    case 0x05:  /* Stereo DAC Power Control */
 693        if ((value & ~s->dac_power) & (1 << 10))
 694            s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 695
 696        s->dac_power = value & 0x9543;
 697#ifdef TSC_VERBOSE
 698        if ((value & ~0x9543) != 0x2aa0)
 699            fprintf(stderr, "tsc2102_audio_register_write: "
 700                            "wrong value written into Power\n");
 701#endif
 702        tsc2102_audio_rate_update(s);
 703        tsc2102_audio_output_update(s);
 704        return;
 705
 706    case 0x06:  /* Audio Control 3 */
 707        s->audio_ctrl3 &= 0x00c0;
 708        s->audio_ctrl3 |= value & 0xf800;
 709#ifdef TSC_VERBOSE
 710        if (value & ~0xf8c7)
 711            fprintf(stderr, "tsc2102_audio_register_write: "
 712                            "wrong value written into Audio 3\n");
 713#endif
 714        tsc2102_audio_output_update(s);
 715        return;
 716
 717    case 0x07:  /* LCH_BASS_BOOST_N0 */
 718    case 0x08:  /* LCH_BASS_BOOST_N1 */
 719    case 0x09:  /* LCH_BASS_BOOST_N2 */
 720    case 0x0a:  /* LCH_BASS_BOOST_N3 */
 721    case 0x0b:  /* LCH_BASS_BOOST_N4 */
 722    case 0x0c:  /* LCH_BASS_BOOST_N5 */
 723    case 0x0d:  /* LCH_BASS_BOOST_D1 */
 724    case 0x0e:  /* LCH_BASS_BOOST_D2 */
 725    case 0x0f:  /* LCH_BASS_BOOST_D4 */
 726    case 0x10:  /* LCH_BASS_BOOST_D5 */
 727    case 0x11:  /* RCH_BASS_BOOST_N0 */
 728    case 0x12:  /* RCH_BASS_BOOST_N1 */
 729    case 0x13:  /* RCH_BASS_BOOST_N2 */
 730    case 0x14:  /* RCH_BASS_BOOST_N3 */
 731    case 0x15:  /* RCH_BASS_BOOST_N4 */
 732    case 0x16:  /* RCH_BASS_BOOST_N5 */
 733    case 0x17:  /* RCH_BASS_BOOST_D1 */
 734    case 0x18:  /* RCH_BASS_BOOST_D2 */
 735    case 0x19:  /* RCH_BASS_BOOST_D4 */
 736    case 0x1a:  /* RCH_BASS_BOOST_D5 */
 737        s->filter_data[reg - 0x07] = value;
 738        return;
 739
 740    case 0x1b:  /* PLL Programmability 1 */
 741        s->pll[0] = value & 0xfffc;
 742#ifdef TSC_VERBOSE
 743        if (value & ~0xfffc)
 744            fprintf(stderr, "tsc2102_audio_register_write: "
 745                            "wrong value written into PLL 1\n");
 746#endif
 747        return;
 748
 749    case 0x1c:  /* PLL Programmability 2 */
 750        s->pll[1] = value & 0xfffc;
 751#ifdef TSC_VERBOSE
 752        if (value & ~0xfffc)
 753            fprintf(stderr, "tsc2102_audio_register_write: "
 754                            "wrong value written into PLL 2\n");
 755#endif
 756        return;
 757
 758    case 0x1d:  /* Audio Control 4 */
 759        s->softstep = !(value & 0x4000);
 760#ifdef TSC_VERBOSE
 761        if (value & ~0x4000)
 762            fprintf(stderr, "tsc2102_audio_register_write: "
 763                            "wrong value written into Audio 4\n");
 764#endif
 765        return;
 766
 767    default:
 768        qemu_log_mask(LOG_GUEST_ERROR, "tsc2102_audio_register_write: "
 769                                       "no such register: 0x%02x\n", reg);
 770    }
 771}
 772
 773/* This handles most of the chip logic.  */
 774static void tsc210x_pin_update(TSC210xState *s)
 775{
 776    int64_t expires;
 777    bool pin_state;
 778
 779    switch (s->pin_func) {
 780    case 0:
 781        pin_state = s->pressure;
 782        break;
 783    case 1:
 784        pin_state = !!s->dav;
 785        break;
 786    case 2:
 787    default:
 788        pin_state = s->pressure && !s->dav;
 789    }
 790
 791    if (!s->enabled)
 792        pin_state = false;
 793
 794    if (pin_state != s->irq) {
 795        s->irq = pin_state;
 796        qemu_set_irq(s->pint, !s->irq);
 797    }
 798
 799    switch (s->nextfunction) {
 800    case TSC_MODE_XY_SCAN:
 801    case TSC_MODE_XYZ_SCAN:
 802        if (!s->pressure)
 803            return;
 804        break;
 805
 806    case TSC_MODE_X:
 807    case TSC_MODE_Y:
 808    case TSC_MODE_Z:
 809        if (!s->pressure)
 810            return;
 811        /* Fall through */
 812    case TSC_MODE_BAT1:
 813    case TSC_MODE_BAT2:
 814    case TSC_MODE_AUX:
 815    case TSC_MODE_TEMP1:
 816    case TSC_MODE_TEMP2:
 817        if (s->dav)
 818            s->enabled = false;
 819        break;
 820
 821    case TSC_MODE_AUX_SCAN:
 822    case TSC_MODE_PORT_SCAN:
 823        break;
 824
 825    case TSC_MODE_NO_SCAN:
 826    case TSC_MODE_XX_DRV:
 827    case TSC_MODE_YY_DRV:
 828    case TSC_MODE_YX_DRV:
 829    default:
 830        return;
 831    }
 832
 833    if (!s->enabled || s->busy || s->dav)
 834        return;
 835
 836    s->busy = true;
 837    s->precision = s->nextprecision;
 838    s->function = s->nextfunction;
 839    expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
 840        (NANOSECONDS_PER_SECOND >> 10);
 841    timer_mod(s->timer, expires);
 842}
 843
 844static uint16_t tsc210x_read(TSC210xState *s)
 845{
 846    uint16_t ret = 0x0000;
 847
 848    if (!s->command)
 849        fprintf(stderr, "tsc210x_read: SPI underrun!\n");
 850
 851    switch (s->page) {
 852    case TSC_DATA_REGISTERS_PAGE:
 853        ret = tsc2102_data_register_read(s, s->offset);
 854        if (!s->dav)
 855            qemu_irq_raise(s->davint);
 856        break;
 857    case TSC_CONTROL_REGISTERS_PAGE:
 858        ret = tsc2102_control_register_read(s, s->offset);
 859        break;
 860    case TSC_AUDIO_REGISTERS_PAGE:
 861        ret = tsc2102_audio_register_read(s, s->offset);
 862        break;
 863    default:
 864        hw_error("tsc210x_read: wrong memory page\n");
 865    }
 866
 867    tsc210x_pin_update(s);
 868
 869    /* Allow sequential reads.  */
 870    s->offset ++;
 871    s->state = false;
 872    return ret;
 873}
 874
 875static void tsc210x_write(TSC210xState *s, uint16_t value)
 876{
 877    /*
 878     * This is a two-state state machine for reading
 879     * command and data every second time.
 880     */
 881    if (!s->state) {
 882        s->command = (value >> 15) != 0;
 883        s->page = (value >> 11) & 0x0f;
 884        s->offset = (value >> 5) & 0x3f;
 885        s->state = true;
 886    } else {
 887        if (s->command)
 888            fprintf(stderr, "tsc210x_write: SPI overrun!\n");
 889        else
 890            switch (s->page) {
 891            case TSC_DATA_REGISTERS_PAGE:
 892                tsc2102_data_register_write(s, s->offset, value);
 893                break;
 894            case TSC_CONTROL_REGISTERS_PAGE:
 895                tsc2102_control_register_write(s, s->offset, value);
 896                break;
 897            case TSC_AUDIO_REGISTERS_PAGE:
 898                tsc2102_audio_register_write(s, s->offset, value);
 899                break;
 900            default:
 901                hw_error("tsc210x_write: wrong memory page\n");
 902            }
 903
 904        tsc210x_pin_update(s);
 905        s->state = false;
 906    }
 907}
 908
 909uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
 910{
 911    TSC210xState *s = opaque;
 912    uint32_t ret = 0;
 913
 914    if (len != 16) {
 915        qemu_log_mask(LOG_GUEST_ERROR,
 916                      "%s: bad SPI word width %i\n", __func__, len);
 917        return 0;
 918    }
 919
 920    /* TODO: sequential reads etc - how do we make sure the host doesn't
 921     * unintentionally read out a conversion result from a register while
 922     * transmitting the command word of the next command?  */
 923    if (!value || (s->state && s->command))
 924        ret = tsc210x_read(s);
 925    if (value || (s->state && !s->command))
 926        tsc210x_write(s, value);
 927
 928    return ret;
 929}
 930
 931static void tsc210x_timer_tick(void *opaque)
 932{
 933    TSC210xState *s = opaque;
 934
 935    /* Timer ticked -- a set of conversions has been finished.  */
 936
 937    if (!s->busy)
 938        return;
 939
 940    s->busy = false;
 941    s->dav |= mode_regs[s->function];
 942    tsc210x_pin_update(s);
 943    qemu_irq_lower(s->davint);
 944}
 945
 946static void tsc210x_touchscreen_event(void *opaque,
 947                int x, int y, int z, int buttons_state)
 948{
 949    TSC210xState *s = opaque;
 950    int p = s->pressure;
 951
 952    if (buttons_state) {
 953        s->x = x;
 954        s->y = y;
 955    }
 956    s->pressure = !!buttons_state;
 957
 958    /*
 959     * Note: We would get better responsiveness in the guest by
 960     * signaling TS events immediately, but for now we simulate
 961     * the first conversion delay for sake of correctness.
 962     */
 963    if (p != s->pressure)
 964        tsc210x_pin_update(s);
 965}
 966
 967static void tsc210x_i2s_swallow(TSC210xState *s)
 968{
 969    if (s->dac_voice[0])
 970        tsc210x_out_flush(s, s->codec.out.len);
 971    else
 972        s->codec.out.len = 0;
 973}
 974
 975static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
 976{
 977    s->i2s_tx_rate = out;
 978    s->i2s_rx_rate = in;
 979}
 980
 981static int tsc210x_pre_save(void *opaque)
 982{
 983    TSC210xState *s = (TSC210xState *) opaque;
 984    s->now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 985
 986    return 0;
 987}
 988
 989static int tsc210x_post_load(void *opaque, int version_id)
 990{
 991    TSC210xState *s = (TSC210xState *) opaque;
 992    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 993
 994    if (s->function >= ARRAY_SIZE(mode_regs)) {
 995        return -EINVAL;
 996    }
 997    if (s->nextfunction >= ARRAY_SIZE(mode_regs)) {
 998        return -EINVAL;
 999    }
1000    if (s->precision >= ARRAY_SIZE(resolution)) {
1001        return -EINVAL;
1002    }
1003    if (s->nextprecision >= ARRAY_SIZE(resolution)) {
1004        return -EINVAL;
1005    }
1006
1007    s->volume_change -= s->now;
1008    s->volume_change += now;
1009    s->powerdown -= s->now;
1010    s->powerdown += now;
1011
1012    s->busy = timer_pending(s->timer);
1013    qemu_set_irq(s->pint, !s->irq);
1014    qemu_set_irq(s->davint, !s->dav);
1015
1016    return 0;
1017}
1018
1019static VMStateField vmstatefields_tsc210x[] = {
1020    VMSTATE_BOOL(enabled, TSC210xState),
1021    VMSTATE_BOOL(host_mode, TSC210xState),
1022    VMSTATE_BOOL(irq, TSC210xState),
1023    VMSTATE_BOOL(command, TSC210xState),
1024    VMSTATE_BOOL(pressure, TSC210xState),
1025    VMSTATE_BOOL(softstep, TSC210xState),
1026    VMSTATE_BOOL(state, TSC210xState),
1027    VMSTATE_UINT16(dav, TSC210xState),
1028    VMSTATE_INT32(x, TSC210xState),
1029    VMSTATE_INT32(y, TSC210xState),
1030    VMSTATE_UINT8(offset, TSC210xState),
1031    VMSTATE_UINT8(page, TSC210xState),
1032    VMSTATE_UINT8(filter, TSC210xState),
1033    VMSTATE_UINT8(pin_func, TSC210xState),
1034    VMSTATE_UINT8(ref, TSC210xState),
1035    VMSTATE_UINT8(timing, TSC210xState),
1036    VMSTATE_UINT8(noise, TSC210xState),
1037    VMSTATE_UINT8(function, TSC210xState),
1038    VMSTATE_UINT8(nextfunction, TSC210xState),
1039    VMSTATE_UINT8(precision, TSC210xState),
1040    VMSTATE_UINT8(nextprecision, TSC210xState),
1041    VMSTATE_UINT16(audio_ctrl1, TSC210xState),
1042    VMSTATE_UINT16(audio_ctrl2, TSC210xState),
1043    VMSTATE_UINT16(audio_ctrl3, TSC210xState),
1044    VMSTATE_UINT16_ARRAY(pll, TSC210xState, 3),
1045    VMSTATE_UINT16(volume, TSC210xState),
1046    VMSTATE_UINT16(dac_power, TSC210xState),
1047    VMSTATE_INT64(volume_change, TSC210xState),
1048    VMSTATE_INT64(powerdown, TSC210xState),
1049    VMSTATE_INT64(now, TSC210xState),
1050    VMSTATE_UINT16_ARRAY(filter_data, TSC210xState, 0x14),
1051    VMSTATE_TIMER_PTR(timer, TSC210xState),
1052    VMSTATE_END_OF_LIST()
1053};
1054
1055static const VMStateDescription vmstate_tsc2102 = {
1056    .name = "tsc2102",
1057    .version_id = 1,
1058    .minimum_version_id = 1,
1059    .pre_save = tsc210x_pre_save,
1060    .post_load = tsc210x_post_load,
1061    .fields = vmstatefields_tsc210x,
1062};
1063
1064static const VMStateDescription vmstate_tsc2301 = {
1065    .name = "tsc2301",
1066    .version_id = 1,
1067    .minimum_version_id = 1,
1068    .pre_save = tsc210x_pre_save,
1069    .post_load = tsc210x_post_load,
1070    .fields = vmstatefields_tsc210x,
1071};
1072
1073uWireSlave *tsc2102_init(qemu_irq pint)
1074{
1075    TSC210xState *s;
1076
1077    s = g_new0(TSC210xState, 1);
1078    s->x = 160;
1079    s->y = 160;
1080    s->pressure = 0;
1081    s->precision = s->nextprecision = 0;
1082    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
1083    s->pint = pint;
1084    s->model = 0x2102;
1085    s->name = "tsc2102";
1086
1087    s->tr[0] = 0;
1088    s->tr[1] = 1;
1089    s->tr[2] = 1;
1090    s->tr[3] = 0;
1091    s->tr[4] = 1;
1092    s->tr[5] = 0;
1093    s->tr[6] = 1;
1094    s->tr[7] = 0;
1095
1096    s->chip.opaque = s;
1097    s->chip.send = (void *) tsc210x_write;
1098    s->chip.receive = (void *) tsc210x_read;
1099
1100    s->codec.opaque = s;
1101    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1102    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1103    s->codec.in.fifo = s->in_fifo;
1104    s->codec.out.fifo = s->out_fifo;
1105
1106    tsc210x_reset(s);
1107
1108    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1109                    "QEMU TSC2102-driven Touchscreen");
1110
1111    AUD_register_card(s->name, &s->card);
1112
1113    qemu_register_reset((void *) tsc210x_reset, s);
1114    vmstate_register(NULL, 0, &vmstate_tsc2102, s);
1115
1116    return &s->chip;
1117}
1118
1119uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
1120{
1121    TSC210xState *s;
1122
1123    s = g_new0(TSC210xState, 1);
1124    s->x = 400;
1125    s->y = 240;
1126    s->pressure = 0;
1127    s->precision = s->nextprecision = 0;
1128    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
1129    s->pint = penirq;
1130    s->kbint = kbirq;
1131    s->davint = dav;
1132    s->model = 0x2301;
1133    s->name = "tsc2301";
1134
1135    s->tr[0] = 0;
1136    s->tr[1] = 1;
1137    s->tr[2] = 1;
1138    s->tr[3] = 0;
1139    s->tr[4] = 1;
1140    s->tr[5] = 0;
1141    s->tr[6] = 1;
1142    s->tr[7] = 0;
1143
1144    s->chip.opaque = s;
1145    s->chip.send = (void *) tsc210x_write;
1146    s->chip.receive = (void *) tsc210x_read;
1147
1148    s->codec.opaque = s;
1149    s->codec.tx_swallow = (void *) tsc210x_i2s_swallow;
1150    s->codec.set_rate = (void *) tsc210x_i2s_set_rate;
1151    s->codec.in.fifo = s->in_fifo;
1152    s->codec.out.fifo = s->out_fifo;
1153
1154    tsc210x_reset(s);
1155
1156    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1157                    "QEMU TSC2301-driven Touchscreen");
1158
1159    AUD_register_card(s->name, &s->card);
1160
1161    qemu_register_reset((void *) tsc210x_reset, s);
1162    vmstate_register(NULL, 0, &vmstate_tsc2301, s);
1163
1164    return &s->chip;
1165}
1166
1167I2SCodec *tsc210x_codec(uWireSlave *chip)
1168{
1169    TSC210xState *s = (TSC210xState *) chip->opaque;
1170
1171    return &s->codec;
1172}
1173
1174/*
1175 * Use tslib generated calibration data to generate ADC input values
1176 * from the touchscreen.  Assuming 12-bit precision was used during
1177 * tslib calibration.
1178 */
1179void tsc210x_set_transform(uWireSlave *chip,
1180                MouseTransformInfo *info)
1181{
1182    TSC210xState *s = (TSC210xState *) chip->opaque;
1183#if 0
1184    int64_t ltr[8];
1185
1186    ltr[0] = (int64_t) info->a[1] * info->y;
1187    ltr[1] = (int64_t) info->a[4] * info->x;
1188    ltr[2] = (int64_t) info->a[1] * info->a[3] -
1189            (int64_t) info->a[4] * info->a[0];
1190    ltr[3] = (int64_t) info->a[2] * info->a[4] -
1191            (int64_t) info->a[5] * info->a[1];
1192    ltr[4] = (int64_t) info->a[0] * info->y;
1193    ltr[5] = (int64_t) info->a[3] * info->x;
1194    ltr[6] = (int64_t) info->a[4] * info->a[0] -
1195            (int64_t) info->a[1] * info->a[3];
1196    ltr[7] = (int64_t) info->a[2] * info->a[3] -
1197            (int64_t) info->a[5] * info->a[0];
1198
1199    /* Avoid integer overflow */
1200    s->tr[0] = ltr[0] >> 11;
1201    s->tr[1] = ltr[1] >> 11;
1202    s->tr[2] = muldiv64(ltr[2], 1, info->a[6]);
1203    s->tr[3] = muldiv64(ltr[3], 1 << 4, ltr[2]);
1204    s->tr[4] = ltr[4] >> 11;
1205    s->tr[5] = ltr[5] >> 11;
1206    s->tr[6] = muldiv64(ltr[6], 1, info->a[6]);
1207    s->tr[7] = muldiv64(ltr[7], 1 << 4, ltr[6]);
1208#else
1209
1210    /* This version assumes touchscreen X & Y axis are parallel or
1211     * perpendicular to LCD's  X & Y axis in some way.  */
1212    if (abs(info->a[0]) > abs(info->a[1])) {
1213        s->tr[0] = 0;
1214        s->tr[1] = -info->a[6] * info->x;
1215        s->tr[2] = info->a[0];
1216        s->tr[3] = -info->a[2] / info->a[0];
1217        s->tr[4] = info->a[6] * info->y;
1218        s->tr[5] = 0;
1219        s->tr[6] = info->a[4];
1220        s->tr[7] = -info->a[5] / info->a[4];
1221    } else {
1222        s->tr[0] = info->a[6] * info->y;
1223        s->tr[1] = 0;
1224        s->tr[2] = info->a[1];
1225        s->tr[3] = -info->a[2] / info->a[1];
1226        s->tr[4] = 0;
1227        s->tr[5] = -info->a[6] * info->x;
1228        s->tr[6] = info->a[3];
1229        s->tr[7] = -info->a[5] / info->a[3];
1230    }
1231
1232    s->tr[0] >>= 11;
1233    s->tr[1] >>= 11;
1234    s->tr[3] <<= 4;
1235    s->tr[4] >>= 11;
1236    s->tr[5] >>= 11;
1237    s->tr[7] <<= 4;
1238#endif
1239}
1240
1241void tsc210x_key_event(uWireSlave *chip, int key, int down)
1242{
1243    TSC210xState *s = (TSC210xState *) chip->opaque;
1244
1245    if (down)
1246        s->kb.down |= 1 << key;
1247    else
1248        s->kb.down &= ~(1 << key);
1249
1250    if (down && (s->kb.down & ~s->kb.mask) && !s->kb.intr) {
1251        s->kb.intr = 1;
1252        qemu_irq_lower(s->kbint);
1253    } else if (s->kb.intr && !(s->kb.down & ~s->kb.mask) &&
1254                    !(s->kb.mode & 1)) {
1255        s->kb.intr = 0;
1256        qemu_irq_raise(s->kbint);
1257    }
1258}
1259